I am compiling a large number of files which use srand() and rand() without including stdlib.h.
I'm aware that this is bad practice but, as I cannot change the files that I am compiling, inserting the necessary include statement in each file is not an option.
How can I configure my compiler to allow implicit inclusion of stdlib functions? Also, is there a way to implicitly use the std namespace in the same way?
Edit: Using g++
Edit: Looks like this is the answer (to the first part, at least). To compile a file as if stdlib.h is included, use the option -include stdlib.h
As you've now mentioned that you're using GCC, you can just use the -include flag. Other compilers probably have equivalents.
If you don't have such a flag for your compiler, you could use the following not-entirely-serious solution, that should work nevertheless:
nice.cc
#include <stdlib.h>
#include "naughty.cc"
(where naughty.cc is the original source file).
Of course, with a suitable build system, you could automatically generate the nice wrapper files.
Since you are already embracing bad practice, how about:
cat > foo.c << EOF
#include <stdlib.h>
#include "file-to-compile.c"
EOF
${CC} foo.c
You're using GCC, so you can use the -include option (from the manual):
Process file as if #include "file" appeared as the first line of the primary source file.
For example:
g++ -include stdlib.h foo.c
Related
I have a question regarding the #include preprocessor directive in C++.
In my program I would like to include a header file from another directory. For this I have used the full path, example:
#include "full/path/to/my/header.hpp"
Now it turns out that header.hpp itself has an include (let's say #include "otherheader.hpp". During compilation, the compiler complains that it cannot find this other header.
What is the best way to handle this problem, considering the fact that I also don't want to write the full path for every header file, especially including those that are only needed "further down the tree"?
You should use your compiler's -I option.
Example with g++:
g++ -I full/path/to/my/
Then in your code you can simply put:
#include "header.hpp"
More information on search path.
Most compilers allow you to specify the root for additional include directories when compiling. For example, in Visual C++ you specify the -I flag. It's also the same for gcc. For example:
compiler -Ipath/to/headers myfile.c
Don't specify full path to includes. Specify include directories to the compiler instead and then just #include <foo> knowing that foo will be found in /some/path/foo because you told the compiler to search /some/path/ for includes. For many compilers this is done with the -I option.
Recently, I met a very annoying problem. I need to compile some old C++ codes which was compiled with a very old g++ version 4.1.2.
I couldn't find g++ version that old now, so I used g++ 4.4.7 to compile it, but there were many errors like error: ‘snprintf’ was not declared in this scope.
After some work, I found g++ 4.1.2 do NOT distinguish <string> from <string.h>, also <stdio> from <stdio.h>, etc.. But g++ 4.4.7 DOES. So these errors happened.
For some reasons, I couldn't modify the old source code. Is there a way that can make the newer g++ ignore the difference between <string> and <string.h>?
Create a directory in your project (let's call it foo);
Create foo/string and foo/string.h as symlinks to whichever header works;
Add -Ifoo to GCC's compilation flags.
Both symlinks will now be used when you include <string> or <string.h>, and will redirect to the actual system header.
I have seen string and string.h usually implemented as just files (the first string filename is without an extension).
To not include the standard include paths you need to specify: -nostdinc
how do I compile a .c or .cpp file using GCC?
I need to include some standard libraries (fstream, string, iostream) - how do I do this?
For clarification, here:
#pragma once
#include <iostream>
#include <fstream>
#include <string>
#include"ocgenerator.h";
#include"structures.h";
#include"util.h";
#include"util2.h";
using namespace std;
(my .h files are in the same directory as the src file)
If I use the command:
gcc src.cpp -o src.o
I get a lot of errors: memcpy, atoi, atol, strncmp, etc, ... "are not declared in this scope". What should I add to the command?
edit: Or is it a scope thing, and do I have to add std:: to all those functions?
memcpy and strncmp are declared in <cstring>, atoi and atol in <cstdlib>. Just include these headers to bring in their declarations.
Side notes :
No semicolon after preprocessor directives, including #include "".
No using namespace std;, especially not in headers !
(Why is "using namespace std" considered bad practice?)
Since you're building a C++ project, don't forget to link with the standard library via -lstdc++, or use g++ which forwards it to the linker for you.
Note that with GCC you don't have to prefix standard C functions with std:: (as they are also declared in the global namespace), but you should anyway for your code to be standard-compliant.
The cplusplus site helps out. If you search for a specific function, on the top you will find the necessary references for the code to compile:
http://www.cplusplus.com/reference/cstdlib/atol/
You can even check in the URL. In this case, you need 'cstdlib'.
Regarding the compiler, there are several available, g++ is a good option.
I also suggest creating a makefile for automating the building process, because it becomes an headache when your codebase grows.
For any library function you use in your code, read the man page for that function to see which header declares it, and #include that header in any source file that uses the function.
For example, man memcpy shows the memcpy(3) man page (the (3) refers to section 3 of the manual; use man 3 memcpy to specify the section).
NAME
memcpy - copy memory area
SYNOPSIS
#include <string.h>
void *memcpy(void *dest, const void *src, size_t n);
...
memcpy is part of the C standard library, and is declared in <string.h>. For C++ you can use <string.h>, but it's probably better to use <cstring>, which puts the function name in the std namespace. In general, each standard C header <foo.h> is duplicated as a C++ header <cfoo>.
I get a lot of errors: memcpy, atoi, atol, strncmp, etc,
memcpy and strncmp are declared in <cstring>. atoi and atol are <cstdlib> (or in <string.h> and <stdlib.h> if you're programming in C rather than in C++).
And be sure to use the g++ command, not the gcc command, to compile C++ source. They both invoke the same compiler (gcc compiles C++ code if the source file name ends in .cpp), but the g++ command adds some options that are needed for C++.
I'm having an issue where I'm adding some includes
#include <stdio.h>
#include <unordered_map>
#include <mysql.h>
Using this command to compile,
g++ -Wl,-Bsymbolic-functions -rdynamic -L/usr/lib/mysql -lmysqlclient -I/usr/include/mysql -DBIG_JOINS=1 -fno-strict-aliasing -DUNIV_LINUX -DUNIV_LINUX -I/usr/include/ -I/usr/include/c++/4.5/bits/ main.c -o program
When i remove the .h on MySQL and stdio it says that it cannot find them, yet it works find on the unordered_map. Wtf?
Some standard library headers are named for example "string", "vector" etc. You will find file "unordered_map" in your include dir, but you won't find file "mysql", only "mysql.h".
Since the ages of C, most headers have had an extension which is typically .h, and they directly correspond to files in the system. In C++ the standard explicitly specifies certain library components as having include directives not including any extension, such as <unordered_map>. These library includes aren't even required to correspond to a file, just that they provide the required interface when included. By contrast, mysql.h and stdio.h and real files that must be included by exact name.
In the case of stdio.h the C++ library defines an include <cstdio> that includes all the features of C's stdio.h but puts them in the std namespace instead of global (which was the only option in C).
The file name extension is not optional! The reason you can say
#include <unordered_map>
instead of
#include <unordered_map.h>
is because the file is actually called "unordered_map", no extension.
C++ does have the cstdio header which wraps C's stdio.h so you can include that instead; but as for MySql.h, I don't know whether they ship such a replacement.
C++ omits the ".h" from it's system header files to differentiate them from the C header files. Detailed here under the section titled "C++ Headers for the Standard C Library"
This is what I'm trying to do:
$ c++ -D GENERATED=build/generated-content main.cpp
My main.cpp file:
#include "GENERATED/header.h"
void f() { /* something */ }
Currently this code fails to compile. How should I fix it? And whether it's possible at all?
It seems you want to use different headers depending on some "compilation profile".
Instead of the -Dsolution, I would rather suggest using the -I directive to specify the include directories.
Given you have the following file tree:
/
debug/
header.h
release/
header.h
main.cpp:
#include "header.h"
/* some instructions, not relevant here */
And in your Makefile (or whatever tool you use), just specify the proper include directory to use, depending on whatever reason you want:
g++ -I debug main.cpp // Debug mode
g++ -I release main.cpp // Release mode
Important foot note: I don't know if you intended to use this as a debug/release switch. However, doing so would be weird: the interface (the included .h files) shouldn't change between release and debug. If you ever need this, the usual way is to enable/disable some parts of the code using defines, mostly in .c (and .cpp) files.
You can't do that directly, but this is possible:
c++ -D "GENERATED=\"build/generated-content\"" main.cpp
#define INCLUDE_NAME() GENERATED "/header.h"
#include INCLUDE_NAME()
EDIT: This solution does not work (see the comments below).
Essentially, any #include statement not conforming to the 'normal' syntax (either #include "" or #include <>) but being of the form #include SOMETHING will cause SOMETHING to be preprocessed, after which it has to conform to one of the 'normal' syntaxes. SOMETHING can be any sequence of pp-tokens.
However in this case, the result (as generated by GCC) is...
#include "build/generated-content" "/header.h"
... which does not conform to one of the 'normal' syntaxes.
I don't believe that is covered in the C++ Standard, so it would be up to the individual compiler vender whether or not to support it. I don't think any do.
However, just about every compiler allows you to specify a search directory for headers. It's usually the /i option.
So it would be:
$ c++ -i build/generated-content main.cpp
My main.cpp file:
#include "header.h"
void f() { /* something */ }