Multiple inclusion error for header file(s) - C [duplicate] - c

This question already has answers here:
How do I use extern to share variables between source files?
(19 answers)
Closed 4 years ago.
I have a relatively small project with only a few files (.c and .h). I have been fighting multiple inclusion errors (I think). So, I created a master.h header file that has each of the other header files that are needed. ALL of the header files have the
#ifndef _MY_HEADER
#define _MY_HEADER
… Header body
#endif
guards to prevent multiple inclusion. Each of my files includes the master.h file at the top. Here is how I would expect this to work.
The first file that was compiled would see the #include "master.h"
Since this is the first time that this file is processed __MASTER would not have been defined yet, so it would process the file.
The compiler would come to the inclusion of the next header file, an similarly, it would have not been processed yet, so the complier would process it, then it would be defined, and would not be processed again.
This continues for all the header files in the master.h until all the files have been processed, and defined so they won't be processed again.
The same is true of the master.h file. Once it's processed, and completed, it won't be processed again due to the guard.
Shouldn't this prevent multiple inclusion?
So here are the errors.
Building target: My_Project_Bootloader.axf
Invoking: GNU ARM C Linker
arm-none-eabi-gcc -g3 -gdwarf-2 -mcpu=cortex-m3 -mthumb -T "C:/Users/Greg/SimplicityStudio/v4_workspace/My_Project_Bootloader/GNU ARM v4.9.3 - Debug/My_Project_Bootloader_custom.ld" -nostdlib -L"C:\GCC_STUFF" --specs=nosys.specs -Xlinker --gc-sections -Xlinker -Map="My_Project_Bootloader.map" -lm -lgcc -lc -o My_Project_Bootloader.axf "./Source/aeabi_memset-thumb.o" "./Source/crt0.o" "./Source/em_emu.o" "./Source/functions.o" "./Source/main.o" "./Source/startup_efm32jg1b.o" "./Source/interrupts.o"
./Source/main.o:(.rodata.const_ModBusIDReg+0x0): multiple definition of `const_ModBusIDReg'
./Source/functions.o:(.rodata.const_ModBusIDReg+0x0): first defined here
collect2.exe: error: ld returned 1 exit status
make: *** [My_Project_Bootloader.axf] Error 1
I've edited/removed some of the information in this post because it turns out it is unrelated. It appears that the "multiple definition" problems the linker was having was not due to actual "multiple definitions", or inclusions for any variable. Instead, it appears as if it was due to declaring and defining the variable (in this case a const in flash) at the same time. Once I split the declaration(s) into a header file, and the actual definition or assignment into a .c file, the problems went away. Here is an example of the fix for one of the problem "variables". I will pay much closer attention to the declaration and definition aspects of variables now. The tools used was GCC. Thank you for all the comments.
// boot.h
// declare const array
const unsigned char const_ModBusIDReg[7][48];
// boot.c
#include boot.h
// define const array
const unsigned char const_ModBusIDReg[7][48] =
{
"String1", // reg00
"String2", // reg01
"String3", // reg02
"String4", // reg03
"String5", // reg04
"String6", // reg05
"String7" // reg06
};

Usually #ifndef HEADER_NAME like you did avoid any including conflicts. But you said "Each of my files includes the master.h" so i suggest that your .c should not include anything else than they own associated .h. (It might already be the case).
Also, beware of including .c.
I don't know about your linker script but what tool do you use to compile ?

The problem is a linker issue, not a per source file issue. It won't be solved by stopping headers from being included multiple times in a single translation unit (TU — source file plus included files).
It appears that you have four symbols (const_ModBusIDReg, const_ModBusRegAttr,
const_ModBusRegDefaults,
const_ModBusRegLimits) which are defined in multiple source files, possibly because you define rather than declare them in a header.
Variables cited in a header must be prefixed with extern — otherwise, they are definitions, not declarations.

Related

Compiler does not give line number of error undefined reference

Why does the compiler sometimes not give line number of the error? Where is the use case of that "undefined reference". I've already included everything as header files I myself wrote so it needs to give a specific line number. It is not closed source. Have I changed some setting of the compiler by accident or is it another thing whatever that another thing is?
D:\Projects\DanceOfPixels\GLEW>gcc main.c glad.c -IC:\mingw_dev_lib\include\SDL2 -LC:\mingw_dev_lib\lib -lmingw32 -lopengl32 -lSDL2main -lSDL2 -lSDL2_image -o main.exe -ansi -std=c89 -pedantic -w
C:\Users\user\AppData\Local\Temp\ccMooHZm.o:main.c:(.text+0x126ce): undefined reference to `drawImagePartScaledHW'
collect2.exe: error: ld returned 1 exit status
Edit: I have solved the problem. I have included two different versions of the draw.h, one coming from software renderer, other from OpenGL renderer. Since they use same
#ifndef DRAW_H
#define DRAW_H
...
#endif
structure for both files; the compiler didn't include the second. Once I've changed the DRAW_H to DRAW_HW I managed to compile and run the application.
That error comes from the "linker" (ld), not the compiler proper.
Typically, the compiler compiles each source file into its own, individual object file, containing just the code and data from that source file. Then, the linker combines one or more object files together, and also links in any needed library functions.
Crucially, there's no problem if a single source file (a single object file) calls an undefined function -- that's normal, if the definition of the function is in another source file, or a library. So that's why it's the linker (not the compiler) that finally discovers that there's not a definition for a function anywhere, that it's truly undefined.
But since the linker is working with object files, typically it doesn't know which source file line numbers the functions were originally called on.
(Some C compilers work more closely with their linkers, so that these "undefined external" error messages can, more usefully, contain actual source file line numbers, but that's a relatively recent innovation. For this to work it may be important to compile with debugging enabled, e.g. by using the -g flag, so that the compiler includes source line number information in its object files.)

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 compile multiple .c and .h files in gcc linux?

So I have a source mainClass.c where I have the main defined. I have a header file class1.h and the implementation of all the functions defined in class1.h in class1.c. I have two variables (global) in class1.h named cond and mutex which are being used in class1.c for now and probably in future I will be using it in my mainClass.c as well.
Now to compile all the source files to generate one object file I am doing something as follows:
gcc -Wall -pthread -I/home/2008/ariarad/mainClass1 mainClass1.c class1.c -o out
/home/2008/ariarad/mainClass1 is where all my header and source files are at and I am using pthead.h in one of the .c file. Even though I have included it there it complains so I had to include it.
Now when I run the above command the I get the following errors:
class1.c:3:16: error: redefinition of ‘cond’
class1.h:66:16: note: previous definition of ‘cond’ was here
class1.c:4:17: error: redefinition of ‘mutex’
class1.h:67:17: note: previous definition of ‘mutex’ was here
Just in case I have an ifndef and endif block surrounding the class1.h to avoid multiple inclusion. I am definitely not redefining the variables defined in the header file in the .c file. So can someone please help me why it is still giving me the errors?
You cannot define global variables in header files. You must define them in one of the .c files, and then use extern in the header files:
In one of the .c files:
int cond;
In one of the .h files, which must be included by all .c files that need the variable:
extern int cond;

Calling methods from multiple C files without custom header files, Makefile Linking

This has gotten a bit lost in translation so I am going to be more precise:
we have classes recursion.c, fib.c, and countUp.c. from recursion.c we have to recursively call fib.c or countUp.c, decided by the input argument. I can't use header files and am only given that I must place prototypes:
int fib(int n);
and
void countUp(int n);
My Makefile
TAR = tar
COMPILER_FLAGS = -g -Wall -std=c99 -c
LINKER_FLAGS = -g -o
OBJS = recurse.o
C_FILES = recurse.c fib.c countUp.c
ASM_FILES = recurse.asm
TARGET_FILE = recurse
TARGET_TAR = PA5.tar
$(TARGET_TAR): $(TARGET_FILE)
$(TAR) -cvf $(TARGET_TAR) $(C_FILES) $(ASM_FILES) $(TARGET_FILE) Makefi$
recurse.o: recurse.c
$(C_COMPILER) $(COMPILER_FLAGS) $(C_FILES)
$(TARGET_FILE): $(OBJS)
$(LD_LINKER) $(LINKER_FLAGS) $(TARGET_FILE) $(OBJS)
where fib and countUp class methods must be called recursively. The recursive.c file is considered our c driver. Do not create or implement any header files OTHER than those that are standard c headers (stdio.h, string.h, etc.). When I try to run this I get:
make
gcc -g -o recurse recurse.o
recurse.o: In function `main':
(file root location)/recurse.c:43: undefined reference to `fib'
(file root location)/recurse.c:46: undefined reference to `countUp'
collect2: ld returned 1 exit status
make: *** [recurse] Error 1
Any clue what is going on.
Original Question:
I have multiple C files that I am combining into an executable. For example say I have math.c, the arguments are passed into it, and then if the input argument calls add it performs functions from add.c, if the argument calls subtract it will call functions from subtract.c, etc. The files are then compiled into a .o file, and then an executable is created. The issue I have is not being able to utilize header (.h) files. Is there any way to break into the separate classes or am I missing something? I really don't know exactly how to ask the question, jargon is pretty bad as far as C goes, sorry :(
I don't really get the idea of a driver I guess. (Not a device driver, she keeps telling us this is a c executable driver).
If I understood correctly, what I think you need to do is add the following prototypes above any of the functions you define in recursion.c. The prototypes will allow you to call these functions from within any function inside recursion.c (In fact, including a header file is akin to copy-pasting all of the prototypes defined in the file, as #Justin and #EdS already pointed out)
int fib(int n);
void countUp(int n);
int main() {
...
}
Then you need to make sure that your project file includes the files recursion.c, fib.c, and countUp.c - When you build your project, the linker will do its job and lookup the entry points in your compiled object files, and will proceed to assemble a single executable file.
What compiler are you using?
Including a header file is just a preprocessor directive to include the contents of that file at the location of the include. To achieve the same thing without a header file just copy and paste the code that you would have put in the header file into the top of each c file.
Of course this isn't very maintainable as if you want to change that contents you need to change it in many files, hence why header files exist in the first place.
Since this is homework and considering the fact that you have told us that A) You have no header files to use, and B) you have not been instructed to utilize the extern keyword, it seems to me that your only choice is to include the .c files themselves:
#include "add.c"
#include "subtract.c"
/* etc... */
int main()
{
// use functions defined in "add.c", "subtract.c", etc.
}
Note that this is bad form as you are including the implementation instead of the interface and likely pulling in a bunch of stuff you don't want or need. If that doesn't answer your question then there is something, some instruction from your teacher, missing in the question.

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

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.

Resources