From what I have understood, the reason you initialize a static member in a .cpp file and not in a .h is so there's no risk to get several instances of the member.Take this example then:
//Foo.h
#ifndef FOO_H
#define FOO_H
class Foo{
static int a;
};
int Foo::a = 95;
#endif
The preprocessor directives make sure that this .h file is only compiled once, which ensures there is only one instance of the static member. Is this possible to do instead of initiate the static member in a .cpp file?
No, it only assures that Foo.h is included once per compilation unit (.cpp file). Not in the entire project. You should define the static member within Foo.cpp
Consider having two source code files, a.cpp and b.cpp, that both include the header. Since they're compiled independently of each other, the header guard will not work, you will end up with two object files a.o and b.o that both define Foo:a. Trying to link them together will fail.
This will cause a linker error if the header is included in multiple .cpp files (translation units):
//a.cpp
#include <Foo.h>
//b.cpp
#include <Foo.h>
After compilation, a.obj contains a definition of Foo::a and b.obj contains a definition of Foo::b. If an attempt is made to link these two .obj files into a single binary a multiple definition error will occur.
No, the include guards ensure that the header is included at most once per compilation unit. If your program has multiple compilation units (.cpp files) including the header then you will end up with multiple definitions for Foo::a.
Related
I have a header file x.h which is included by more than one *.c source files.
This header file has some structure variables defined.
I have put multiple inclusion prevention guard at the beginning of the header file as:
#ifndef X_H
#define X_H
...
..
//header file declarations and definitons.
#endif//X_H
On building I get linker errors related to multiple definitions. I understand the problem.
Won't a multiple inclusion prevention guard at the top of header file as I have, prevent multiple inclusions of the header file x.h and thereby avoid multiple definitions of the variables that are there in x.h?
#pragma once does not work on this particular compiler, so what is the solution?
Someone had posted this answer to a similar question. It doesn't seem to work for me. How does this solution work?
If the linker is complaining, it means you have definitions rather than just declarations in your header. Here's an example of things that would be wrong.
#ifndef X_H
#define X_H
int myFunc()
{
return 42; // Wrong! definition in header.
}
int myVar; // Wrong! definition in header.
#endif
You should split this into source and header file like this:
Header:
#ifndef X_H
#define X_H
extern int myFunc();
extern int myVar;
#endif
C Source:
int myFunc()
{
return 42;
}
int myVar;
Header guards are only good for a single compilation unit, i.e., source file. If you happen to include a header file multiple times, perhaps because all headers included from main.c in turn include stdio.h then guards will help.
If you have the definition of a function f in x.h which is included by main.c and util.c, then it is like copying and pasting the definition of f into main.c when creating main.o and doing the same for util.c to create util.o. Then the linker will complain and this happens despite your header guards. Having multiple #include "x.h" statements in main.c is possible of course because of these guards.
Using include guards prevents one compilation unit from including the header twice. E.g. if header B.h includes A.h and B.cpp includes A.h and B.h, everything from A.h would be declared twice in the compilation B.cpp if you weren't using include guards.
Your include guards prevent this from happening, all's fine till now.
But you get multiple definitions at link time, i.e. two compilation units define the same thing, this probably means you got a real definition in your header, use extern for all variables, make sure functions are either inline or are defined in the cpp file.
If the functions aren't large, you can use "inline" before them and the linker won't complain.
Using a multiple inclusion guard prevents compiler errors, but you're getting a linker error. Do you have data definitions in the header file that don't use extern?
Maybe X_H is already defined somewhere else? I just ran into this issue, where Xlib defines X_H in /usr/include/X11/X.h.
To check, you can call gcc -dM -E (if you are using gcc), e.g. in the buildsystem I’m using that works with CC=gcc CFLAGS="-dM -E" make. If the output file contains #define X_H even though you remove it from your file (use Y_H for example), then it is already defined outside your source code.
I have a header file x.h which is included by more than one *.c source files.
This header file has some structure variables defined.
I have put multiple inclusion prevention guard at the beginning of the header file as:
#ifndef X_H
#define X_H
...
..
//header file declarations and definitons.
#endif//X_H
On building I get linker errors related to multiple definitions. I understand the problem.
Won't a multiple inclusion prevention guard at the top of header file as I have, prevent multiple inclusions of the header file x.h and thereby avoid multiple definitions of the variables that are there in x.h?
#pragma once does not work on this particular compiler, so what is the solution?
Someone had posted this answer to a similar question. It doesn't seem to work for me. How does this solution work?
If the linker is complaining, it means you have definitions rather than just declarations in your header. Here's an example of things that would be wrong.
#ifndef X_H
#define X_H
int myFunc()
{
return 42; // Wrong! definition in header.
}
int myVar; // Wrong! definition in header.
#endif
You should split this into source and header file like this:
Header:
#ifndef X_H
#define X_H
extern int myFunc();
extern int myVar;
#endif
C Source:
int myFunc()
{
return 42;
}
int myVar;
Header guards are only good for a single compilation unit, i.e., source file. If you happen to include a header file multiple times, perhaps because all headers included from main.c in turn include stdio.h then guards will help.
If you have the definition of a function f in x.h which is included by main.c and util.c, then it is like copying and pasting the definition of f into main.c when creating main.o and doing the same for util.c to create util.o. Then the linker will complain and this happens despite your header guards. Having multiple #include "x.h" statements in main.c is possible of course because of these guards.
Using include guards prevents one compilation unit from including the header twice. E.g. if header B.h includes A.h and B.cpp includes A.h and B.h, everything from A.h would be declared twice in the compilation B.cpp if you weren't using include guards.
Your include guards prevent this from happening, all's fine till now.
But you get multiple definitions at link time, i.e. two compilation units define the same thing, this probably means you got a real definition in your header, use extern for all variables, make sure functions are either inline or are defined in the cpp file.
If the functions aren't large, you can use "inline" before them and the linker won't complain.
Using a multiple inclusion guard prevents compiler errors, but you're getting a linker error. Do you have data definitions in the header file that don't use extern?
Maybe X_H is already defined somewhere else? I just ran into this issue, where Xlib defines X_H in /usr/include/X11/X.h.
To check, you can call gcc -dM -E (if you are using gcc), e.g. in the buildsystem I’m using that works with CC=gcc CFLAGS="-dM -E" make. If the output file contains #define X_H even though you remove it from your file (use Y_H for example), then it is already defined outside your source code.
For example, I have a class Foo. I create Foo.h, Foo.cpp and then I include Foo.h in the main.cpp file. When I compile the code, how does the machine know to associate the class header file and the class cpp file? Is it done by the filenames?
I'm really interested in understanding this process of compilation and linking.
When i compile the code how does the machine know to associate the class header file and the class cpp file? is it doing it by the files name?
No, there's no such kind of automatic association done by the compiler.
If you have a header file containing all the declarations of functions and classes, it must be #included from any translation unit (.cpp file), that makes use of it.
That step (of declaration contracts) is done by the c-preprocessor where every occurrence of #include "MyDeclarations.hpp" replaces that with the complete file content of MyDeclarations.hpp in the translation unit.
A simple example:
Foo.hpp
class Foo {
public:
Foo(); // Constructor declaration
};
Foo.cpp
#include "Foo.hpp" // <<<< Include declarations
Foo::Foo() {} // Constructor definition
main.cpp
#include "Foo.hpp" // <<<< Include declarations
int main() {
Foo foo; // <<<<< Use declarations
}
To finally instruct your linker to stich all of these files together you have to refer to the artifacts produced from the translation units. Depending on the toolchain a bit, but for e.g. GCC you may use some compiler command line like
$ g++ main.cpp Foo.cpp -o myProg
I have three files in my project.
a.c
b.c
test.h
test.h declares a
namespace test_namespace {
int i;
void f1();
};
test.h is also surrounded by
#ifndef __x
#define __x
...
#endif
now, a.c includes test.h and b.c also includes test.h .
a.c has the main() function, and b.c has the implementation of test_namespace::f1()
However, on compiling this, I get a linking error -
"test_namespace::i is already defined in <b.c's object file mapping in /tmp>"
If I've taken care to include conditional compilation preprocessor directives in test.h, why is it being included in both files a.c and b.c ?
Also is noteworthy that if I compile b.c separately as a shared library and then use it as a shared library while linking a.c's object file, i don't get this error.
Can someone please explain the above error to me, specially in the face of the conditional compilation directives ?
You cannot declare variables inside a headerfile.
The symbol test_namespace::i becomes exported by both a.c and b.c. The linker find's both and doesn't know which one to use.
What you want to do in test.h is:
namespace test_namespace {
extern int i;
void f1();
}
and then declare test_namespace::i in eather a.c or b.c:
namespace test_namespace {
int i;
}
Conditional inclusion is used to prevent headers from being included twice for the same source file not for the whole project. Suppose you have headersa.h and b.h, and b.h #includes a.h. Then if c.c needs things from both headers, it #include both of them. Since the C preprocessor using literal text substitution, when it includes b.h, there will now be two #include "a.h" directives in your file, wreaking the havoc of multiple declarations. (Edit: clarify why you run into problems in this case.)
Include guards are there to protect multiple header inclusions in the build of a compilation unit. They aren't necessary for cases when you have two separate code files and one header, like your example.
(So think more when test.c uses a.h and b.h, in those cases where b.h needs to #include a.h.)
But that's a note about what the include guard convention does and how it isn't buying you anything in this case. The specific technical issue you hit (as others have pointed out) is that you're basically defining the same variable in two different object files, and when the linker goes to pull everything together it doesn't know if you want the variable from a.o or b.o.
( Note: While compilers can generally be set to override things and build C++ code using features like namespace even if the extension is .c - you probably should be using something else, like .cpp: C++ code file extension? .cc vs .cpp )
You're defining test_namespace::i in the header. What you probably
want is extern int i; in the header, and a definition in one of the
source files.
What's happening is that when you say
int i;
this actually does two things:
1) Declares the symbol i
2) Reserves some space and a symbol for i in the object file
The trick is that (1) should only be done once per file (actually you can repeat it in this case) -- which is why you have the conditional include, which you have done correctly -- but (2) should only be done once per program
The solution is to have the header do
// Only declare -- don't create a symbol
extern int i;
And in the *.c file do
int i;
The header guards (#ifndef .. #define .. #endif) are working as they should. Both a.c and b.c include test.h, so they both get a copy of that header. (When you compile a program, what #include does is to literally copy-paste the contents of the header inside the source file.)
Since they both have a copy of the header, they both define the variable test_namespace::i. When the linker tries to link the code generated from a.c with the code generated from b.c it finds that they both define that variable. It doesn't know what to do, so it doesn't complete and outputs an error.
In C++, what is the convention for including headers for class files in the "main" file. e.g.
myclass.h
class MyClass {
doSomething();
}
myclass.cpp
doSomething() {
cout << "doing something";
}
run.cpp
#include "myclass.h"
#include "myclass.cpp"
etc..
Is this relatively standard?
You don't include the .cpp file, only the .h file. The function definitions in the .cpp will be compiled to .obj files, which will then be linked into the final binary. If you include the .cpp file in other .cpp files, you will get two different .obj files with the same funciton definition compiled, which will lead to linker error.
See Understanding C Compilers for a lot of good answers to this question.
You can say one .cpp file and all its included headers make up one translation unit. As the name implies, one translation unit is compiled on its own. The result, often called file.o or file.obj, of each translation unit, is then linked together by the linker, fixing up yet unresolved references. So in your case you have
Translation Unit 1 = run.cpp: myclass.h ...
Translation Unit 2 = myclass.cpp: myclass.h ...
You will have your class definition appear in both translation units. But that's OK. It's allowed, as long as both classes are equally defined. But it's not allowed to have the same function appear in the two translation units if the function is not inline. Not inline functions are allowed to be defined only once, in one single translation unit. Then, you have the linker take the result of each translation unit, and bind them together to an executable:
Executable = mystuff: run.o myclass.o ...
usually you compile the .cpp file separately and link the resulting .o with other .o's
So myclass.cpp would include myclass.h and would be compiled as a unit.
You compile cpp files separately. If you include any given cpp file into two or more cpp files yoy might encounter a conflict during linking phase.
You don't include one *.cpp inside another *.cpp. Instead:
myclass.h
class MyClass {
doSomething();
}
myclass.cpp
#include "myclass.h"
MyClass::doSomething() {
cout << "doing something";
}
run.cpp
#include "myclass.h"
etc..
Instead of including myclass.cpp inside main.cpp (such that the compiler would see both of them in one pass), you compile myclass.cpp and main.cpp separately, and then let the 'linker' combine them into one executable.