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 ?
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.cusesa.handb.h, in those cases whereb.hneeds to #includea.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.oorb.o.( Note: While compilers can generally be set to override things and build C++ code using features like
namespaceeven if the extension is.c– you probably should be using something else, like.cpp: C++ code file extension? .cc vs .cpp )