Why aren't my compile guards preventing multiple definition inclusions? - c

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.

Related

How to stop the inclusion of file imported in a file , the file in which the latter has been included in C

Like a.c has the code
#include "b.h"
b.h has:
#include "c.h"
c.h has:
void fun()
{
}
here i want to restrict a.c from acessing fun but I want b.h to access c.h
If file A.c includes file B.h, and file B.h includes file C.h, and file C.h contains function func - then A can call func - this is just how the language works.
What you can do instead is to move C.h's import into a B.c - which isn't included in A.c - and thus prevent the inclusion of func in A.c. But then you have to separate B into .h and .c - and compile B.c explicitly.
As John pointed out in the comments, you should add include guards to every .h file, e.g.:
#ifndef _B_H_
#define _B_H_
...
#endif
This prevents function declarations from getting reincluded. Also - it is bad practice to implement functions (e.g. int func() { }) in your .h files - instead you should include only their definition (e.g. int func();) and move their implementation to a separate .c file.
In the first place, this ...
here i want to restrict a.c from acessing fun
... has nothing in particular to do with header files or #include. If fun is defined as an external function anywhere in the program, then it can be called from anywhere else in the program, headers notwithstanding. This is merely a question of knowing the function's name and at least something about its signature. With that information, any source file can provide its own compatible declaration of the function to enable the call (and some compilers might even accept the call without a declaration).
If you want to restrict the locations from which fun() can be called (directly, by name) then declare it static, and move its definition to the (only) C source file from which you want it to be callable.
As far as ...
How to stop the inclusion of file imported in a file , the file in
which the latter has been included in C
... goes, you can't do that, strictly speaking. If a.c contains an #include "b.h" directive that is processed, and, in the context of processing that directive, b.h contains an #include "c.h" directive that is processed then the effect is to include the contents of c.h in a.c. Period.
If b.h contains an #include directive that you want to avoid being processed under some circumstances then conditional compilation directives (#if, #ifdef, #ifndef) are the way to do so. "Include guards" are a particularly common example, and as a matter of style and convention, every header should guard its body via appropriate include guards. If your c.h did that then it would resolve the duplicate function definition error you get from a.c directly including both b.h and c.h:
c.h
#ifndef C_H
#define C_H
// everything else ...
#endif
Of course, b.h should have its own include guards, too.
But even more importantly, avoid putting function or variable definitions in header files in the first place. Put only declarations into header files (and provide prototypes):
void f(void);
The actual definitions belong in regular source files (.c), and regular source files should never be #included by any other file. This is the way to share declarations of external functions and objects among translation units without inviting duplicate definitions.

Multiple application header files included error in C

I am doing a porting project implemented from INTEGRITY OS to UBUNTU. Facing compiler error as explained below. Even though not compiled in INTEGRITY OS, i think there is no errors there.
I got the root cause. I am expecting solution how i can achieve this.
main.c
#include "file1.h"
#include "file2.h"
#include "file3.h"
.
.
.
Inside all the files from
file1.h to file3.h below is there at the beginning of each file.
#ifdef INC_HEADER_FILE
#error Multiple header files included.
#endif
#define INC_HEADER_FILE
.
.
.
Above throws error while compiling
In file included from ../main.c:
../file1.h: error: #error Multiple application header files included.
# error Multiple application header files included.
^~~~~
Same error is thrown for all the files for file1.h to file3.h
If all three (or however many there are) of those header files use the same symbol INC_HEADER_FILE, then you will only be allowed to include one of them.
That's because including (for example) file1.h will set that symbol, meaning that including the next header will complain because it's already defined.
The include guard symbol is usually specific to the header file itself, such as INC_HEADER_1_FILE but it's my no means necessary - I've seen this sort of thing done when you only want one variation of a header file.
An example of that is a system I worked on for LED display devices where each header had different dimensions. These were constructed from 8x8 units but different quantities across and down. Having the LED addressing map in a header file allowed for efficiencies that weren't available with dynamic configuration and the include guard made sure we didn't try to use more than one map.
regarding the include guard for header1.h suggest:
#ifndef HEADER1_H
#define HEADER1_H
...
#endif
regarding the include guard for header2.h suggest:
#ifndef HEADER2_H
#define HEADER2_H
....
#endif
and similar for each header file.
The result is in any one compilation unit (source file.c) any specific header file can only be included once.

Macro used in a .c file getting compiled without adding the header file in which it is defined

I have a large project where some macro is defined as:
#define RECORD_COUNT 141 // in one file file1.h
Another file say file2.c is using this macro. But the file2.c is not including file1.h.
So is there a possibility that in on compiling the first file get pre-compiled is file1.h and the macro is added to the global scope. And this makes it possible to pre-compile the file2.c?
Very likely your macro definition are compiling before you are using it somewhere.
Just to check you can use pragma message to check if compiler touches that code.
http://msdn.microsoft.com/en-us/library/x7dkzch2.aspx
You do not need to include the header file directly to use it. There can be indirect includes as well.
For example,
Say file1.h has
#define RECORD_COUNT 141
file2.h has,
#include "file1.h"
...
...
If file2.c has #include "file2.h" then, you can use any macros or definition that are in 'file1.h' inside file2.c after that include statement.

EXPORT_SYMBOL in header causes "exported twice" errors

I have a header file with the declaration of several global variables in the following format:
constants.h
#ifndef CONSTANTS_H
#define CONSTANTS_H
extern unsigned var;
EXPORT_SYMBOL(var);
#endif
constants.c
#include "constants.h"
unsigned var = 10;
foo.c
#include "constants.h"
When I try to compile the kernel module, I get the following error for each respective exported symbol:
WARNING: /home/vilhelm/proj/constants: 'var' exported twice. Previous export was in /home/vilhelm/proj/foo.ko
I suspect that the symbols are being exported every time I include the constants.h header file, but I don't understand why. Shouldn't the include guard in constants.h prevent the EXPORT_SYMBOL(var) from being read multiple times?
Shouldn't the include guard in constants.h prevent the
EXPORT_SYMBOL(var) from being read multiple times?
The include guard prevents the header from being included more than once in the same source file. It can't prevent it from being included via multiple source files. Remember that the objects from all the sources get linked into a single object, and hence the conflict.
Let's say you have another header that is also included in the source files, called foo.h, which in turn includes constants.h. The file constants.c will try to include constants.h twice (once directly via constants.h and again via foo.h). The include guard works here, and constants.h will only be included once.
Same thing will happen with foo.c. It will try to include constants.h twice (once directly via constants.h and again via foo.h). The include guard works here too, and constants.h will only be included once.
But then the two objects, constants.o and foo.o will be linked together, each with its single copy of the EXPORT via constants.h. This adds up to two.
You want to make sure that exports appear in the final link just once. One way to do that would be to take them out of a common file like constants.h, and move them to a file called exports.c.

How to prevent multiple definitions in C?

I'm a C newbie and I was just trying to write a console application with Code::Blocks. Here's the (simplified) code:
main.c:
#include <stdio.h>
#include <stdlib.h>
#include "test.c" // include not necessary for error in Code::Blocks
int main()
{
//t = test(); // calling of method also not necessary
return 0;
}
test.c:
void test() {}
When I try to build this program, it gives the following errors:
*path*\test.c|1|multiple definition of `_ test'|
obj\Debug\main.o:*path*\test.c|1|first defined here|
There is no way that I'm multiply defining test (although I don't know where the underscore is coming from) and it seems highly unlikely that the definition is somehow included twice. This is all the code there is.
I've ruled out that this error is due to some naming conflict with other functions or files being called test or test.c. Note that the multiple and the first definition are on the same line in the same file.
Does anyone know what is causing this and what I can do about it? Thanks!
You actually compile the source code of test.c twice:
The first time when compiling test.c itself,
The second time when compiling main.c which includes all the test.c source.
What you need in your main.c in order to use the test() function is a simple declaration, not its definition. This is achieved by including a test.h header file which contains something like:
void test(void);
This informs the compiler that such a function with input parameters and return type exists. What this function does ( everything inside { and } ) is left in your test.c file.
In main.c, replace #include "test.c" by #include "test.h".
A last point: with your programs being more complex, you will be faced to situations when header files may be included several times. To prevent this, header sources are sometimes enclosed by specific macro definitions, like:
#ifndef TEST_H_INCLUDED
#define TEST_H_INCLUDED
void test(void);
#endif
The underscore is put there by the compiler and used by the linker. The basic path is:
main.c
test.h ---> [compiler] ---> main.o --+
|
test.c ---> [compiler] ---> test.o --+--> [linker] ---> main.exe
So, your main program should include the header file for the test module which should consist only of declarations, such as the function prototype:
void test(void);
This lets the compiler know that it exists when main.c is being compiled but the actual code is in test.c, then test.o.
It's the linking phase that joins together the two modules.
By including test.c into main.c, you're defining the test() function in main.o. Presumably, you're then linking main.o and test.o, both of which contain the function test().
You shouldn't include other source files (*.c) in .c files. I think you want to have a header (.h) file with the DECLARATION of test function, and have it's DEFINITION in a separate .c file.
The error is caused by multiple definitions of the test function (one in test.c and other in main.c)
I had similar problem and i solved it following way.
Solve as follows:
Function prototype declarations and global variable should be in test.h file and you can not initialize global variable in header file.
Function definition and use of global variable in test.c file
if you initialize global variables in header it will have following error
multiple definition of `_ test'|
obj\Debug\main.o:path\test.c|1|first defined here|
Just declarations of global variables in Header file no initialization should work.
Hope it helps
Cheers
Including the implementation file (test.c) causes it to be prepended to your main.c and complied there and then again separately. So, the function test has two definitions -- one in the object code of main.c and once in that of test.c, which gives you a ODR violation. You need to create a header file containing the declaration of test and include it in main.c:
/* test.h */
#ifndef TEST_H
#define TEST_H
void test(); /* declaration */
#endif /* TEST_H */
If you have added test.c to your Code::Blocks project, the definition will be seen twice - once via the #include and once by the linker. You need to:
remove the #include "test.c"
create a file test.h which contains the declaration:
void test();
include the file test.h in main.c
If you're using Visual Studio you could also do "#pragma once" at the top of the headerfile to achieve the same thing as the "#ifndef ..."-wrapping. Some other compilers probably support it as well ..
.. However, don't do this :D Stick with the #ifndef-wrapping to achieve cross-compiler compatibility. I just wanted to let you know that you could also do #pragma once, since you'll probably meet this statement quite a bit when reading other peoples code.
Good luck with it
Ages after this I found another problem that causes the same error and did not find the answer anywhere. I thought to put it here for reference to other people experiencing the same problem.
I defined a function in a header file and it kept throwing this error. (I know it is not the right way, but I thought I would quickly test it that way.)
The solution was to ONLY put a declaration in the header file and the definition in the cpp file.
The reason is that header files are not compiled, they only provide definitions.

Resources