C/C++ - Conditional header file inclusion not working - c++

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.

Related

(.bss+0x0): multiple definition of `player'; [duplicate]

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.

Multiple definition of even with header gaurd [duplicate]

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.

Conditional compilation confusion and failure

I want to compile different files with a common *.c file. Like I want to compile A.c common.c xor B.c common.c but I can't figure out how to achieve that.
Can you please tell me how do I make common.c use different headers without using my text editor to change the headers list every time I want to compile
So let's say I have 3 files: A.c, B.c and common.c.
A.h and B.h define an enum enum {Mon, Tues, Wed...} in different ways. And that enum is used in common.c. So I can't just do in common.c:
#include "A.h"
#include "B.h"
What I thought of doing is to use preprocessor directives:
In common.h
#define A 1
#define B 2
In A.c
#define COMPILE_HEADER A
And in common.c
#if COMPILE_HEADER == A
#include A.h
#end
This doesn't work, of course, because the compiler didn't visit the A.c file to find #define COMPILE_HEADER A
So can you please tell me how do I make common.c use different headers without using my text editor to change the headers list every time I want to compile?
It's pretty complicated to explain, but I'll give it a try.
Explaination
The compiler, for example gcc, gets the input files provided, includes (literally just copy-pastes) the header files into their respective places (where the #include directive is located) in the *.c file, then compiles the file to the object (*.o) file. No executable is created. Here comes the linker, which is included in gcc. It takes the *.o files and links them into one executable.
The problem is, that the files are compiled independently, and then linked together. I mean, that predefinition like int func(int param); is like saying to compiler "Hey man, don't worry about any usage of func in the code, the linker will care". Compiler then just saves this usage as external symbol in the corresponding *.o file, and when linker is doing his job, he firstly finds the location of the symbol definition (the function implementation) and then just points to it whenever the func is called.
Try to include function definition in header file, then include it in 2 or more files from same project (compiled/linked together). Compiler will say it's ok, since the code is correct and the generated code is valid. Then, the linker will try to link it into one executable and he would have to decide which version of the same name-param function should it link to. Since most developer tools are not really good at making the right choices, he will just yell at you saying "hey man, you gave me two definitions of same function, what to do now?". This results with an error like this:
obj\Release\b.o:b.cpp:(.text+0x0): multiple definition of 'func(int)'
obj\Release\a.o:a.cpp:(.text+0xc): first defined here
What about having two main in one project?
obj\Release\b.o:b.cpp:(.text.startup+0x0): multiple definition of 'main'
obj\Release\a.o:a.cpp:(.text.startup+0x0): first defined here
Both files compile, but they cannot be linked together.
The header files are meant to contain class definitions and function predefinitions to allow you to write them only once, and then share between all files that want to use them. You can always just type class definitions for each file separately (as long as they stay same) and use them just like you would use them in .h file, same applies for function predefinitions.
There comes your problem. You have to compile only one file, not include only one. You can do this by using the preprocessor trick, but I wouldn't reccomend as solution, since it can be solved much easier (I'll tell you how in a moment).
TL;DR; (The actual answer without explaination)
You can #ifdef / #ifndef both files, then in another *.c define (or not define) some value. For example:
A.cpp
#include "t.h"
#ifdef USE_A
int func(int a)
{
return a + 5;
}
#endif
B.cpp
#include "t.h"
#ifndef USE_A
int func(int a)
{
return a * 10;
}
#endif
T.h
#ifndef T_H
#define T_H
//Or comment to use B
#define USE_A
int func(int a);
#endif // T_H
main.cpp
#include <iostream>
#include "t.h"
using namespace std;
int main()
{
cout << func(3);
}
Notice that the #ifdef/#ifndef are after the #include, so the preprocessor knows which one to compile. Also, it's not possible (at least I can't think of any way) to make the definition in any .c file, because they are compiled separately (as described above). You could use the -D switch, but that involves messing with build configurations in environments and if you want to do that it's better to try the second solution presented bellow.
Better answer
You should choose one file to compile with each version. It hardly depends on your needs, but basically instead of using g++ main.cpp a.cpp b.cpp you should compile either a.cpp or b.cpp. If you are using integrated environment like Visual Studio or Code Blocks, the configuration managers allow you to decide which file to include. I mean, those Debug/Release dropdowns can contain your own entries, which will customize your project. Then, switching between the A.cpp and B.cpp is just a question of choosing appropiate option in the always-visible bar in your environment.
If you want a more detailed tutorial on how to manage configurations on Code::Blocks or Visual Studio create appropiate question on stackoverflow and it will be answered in no time :)

difference in including header in .cpp and .h

I have a code in which I #include<linux/videodev2.h>. There are three files:
one header file- includes: stdint.h and stdlib.h. Defines a couple of functions, a struct, say abc, and some #define macros. One of the functions is
int func(int, uint32_t, size_t, abc*);
one cpp file with a lot of methods, including definition of the functions in the .h file.
one main.cpp which has main() which has a function call to the method in the .h file (complete file below). This file is only for testing purposes.
#include "head.h"
int main() {
func(5, (uint32_t)5, (size_t)5, 0);
return 0;
}
What is see is a curious case:
If I include linux/videodev2.h only in .h file, uint32_t and other things defined in this header are not accessible by the .cpp files. (erros I get are: uint32_t was not declared in this scope, and uint32_t does not name a type, among others). This happens even if the first line of the .h file is #include<linux/videodev2.h>
If I include the videodev2 header in both the cpp files, it works only if I import it (videodev2) before the .h file.
If I use func(5, (uint32_t)5, (size_t)5, (abc*)0); in the main.cpp file, I get the error that abc is not declared in this scope.
I am compiling using the command: g++ main.cpp head.cpp
I am unable to figure out why is this. I would like to include the videodev2 header in the .h file since, it is almost certain that the code using the .h file will be dependent on it. But it seems that including it in .h file has no effect at all.
I must be honest here. This was C code which I had to convert to C++. I know that I am not conforming to the best practices and standards. But why is this behaviour seen?
Remember that the #include directive indicates to the preprocessor the contents of the specified file should be treated as if they appeared directly in the source file in place of the directive (paraphrased from MSDN).
With that in mind, it seems like you are encountering improper order of #includes and also missing #includes. My guess would be that you are not including your own header file in your .cpp files. This would explain cases one and three. Consider the following files:
// header.h
// #include <linux/videodev2.h> <-- Option 1
class A {
void func(uint32_t var);
};
// header.cpp
void A::func(uint32_t var) {
// implementation
}
// main.cpp
// #include <linux/videodev2.h> <-- Option 2
#include "header.h"
// #include <linux/videodev2.h> <-- Option 3
int main() {
// implementation; something creates an instance of A and calls func
}
Now, Option 1 is not exactly desirable; it's good practice to avoid #includes in header files because they can increase build times and create unwanted dependencies. However, it will ensure that the types header.h requires are there for it to use. The essential bit is that the contents of linux/videodev2.h have to appear before the contents of header.h, anywhere that header.h is #included.
This brings me to Option 2. Option 2 will also compile correctly, because linux/videodev2.h is included before your header, and your header relies on types defined in it. Also important is that both main.cpp and header.cpp must #include "header.h", because they reference symbols declared in it.
If you were to go with Option 3, you would get compilation errors that the type uint32_t is not defined, and the compiler would point to your header file. This is because the contents of the header file appear before the contents of linux/videodev2.h, and so the compiler does not yet understand what the type uint32_t is when it encounters it.
So, given all that, you have choices: include `linux/videodev2.h' before each include of your own header file, or include it directly in your header file. I mentioned earlier that the latter is not good practice, but for your particular case, it might be the better option of the two, in case your header file needs to be included in many .cpps.
I think this would be a good opportunity to dive into precompiled headers, but I'm not as well-versed in them, so I'd leave it to someone who has more experience to explain them.
Hope this helps :)
Found the answer. There was .h.gch file in the directory. I didn't know about precompiled header. Thanks ktodisco for the insight. I still have no idea why that file was there in the first place.

Swap out generally used functions in C++

Hey there,
I have a big code file currently in C++ with many functions which I often use in different versions of my program so I thought about swapping out the generally used functions: E.g. I have:
void doSomething(mxArray *in)
{
mexPrintf("Hello Matlab");
}
whereas mxArray and mexPrintf are defined in another file which comes from matlab (mex.h). In the mainfile I have now:
#include "mex.h"
#include "_general.h"
and I wonder that I didn't get any compiler errors when not including mex.h in _general.cpp also because the file itself NEEDs it obviously. Would you better do the include or doesn't it matgter in this case it is included AFTER mex.h has already been included in the mainfile?
Thanks!
C++ (unlike C) will refuse to make dubious assumptions about the signature of functions for which it hasn't seen a declaration, and compilation will fail with an error message. If you don't get an error, then some header is picking up a declaration for that function. If you can't find it, then try running only the preprocessor stage (e.g. for GCC you'd use g++ -E) and inspecting the output to see the declaration... your compiler may leave comments about which file has included bits of code which can be helpful in understanding the situation.
For example, if _general.cpp includes _general.h which includes mex.h then that's workable, and there's no need to include it directly from _general.cpp. But, if it can be removed from _general.h as it's only needed in the implementation of "general", then that's much better again.
If some other code, say "libraryX" uses mex.h for it's internal needs without exposing mex-related functionality through its public API, then it's better NOT to assume it will continue to include mex.h for you and include it yourself.
As Tamás pointed out, #include directive literally includes the header file into your source code. You can check this using the pre-processor (part of gcc)
$ cat a.cpp
#include "b.h"
int main() {
return b();
}
$ cat b.h
#ifndef _B_H
#define _B_H
int b()
{
return 0;
}
#endif
$ cpp a.cpp
# 1 "a.cpp"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "a.cpp"
# 1 "b.h" 1
int b()
{
return 0;
}
# 2 "a.cpp" 2
int main() {
return b();
}
$
As you can see, if you include the same file twice (which is frequently the case in any moderately complex program involving multiple source files), you run into the problem of having the same function defined twice. To solve this problem, the standard way is to use the 'include guards' (#ifndef, #define and #endif in b.h). That way, whenever you include b.h, a constant is defined. When you include b.h again, pre-processor checks this constant and decides not to include it again.
Of course, care should be taken in choosing the name of the constant :)
If you follow this rule, you can ideally include any header file anywhere. It is generally good idea to include the header file where it is absolutely necessary and without which compilation will fail. Also, a good practice is to include standard header files before custom header files.
HTH!