I'm experiencing a very strange (and annoying) linker error on my project.
Say for example I have the file KernelExports.h:
#pragma once
extern "C"
{
DWORD* KeTimeStampBundle;
DWORD KeGetCurrentProcessType();
//etc...
}
I then #include this in my stdafx.h and then add #include "stdafx.h" all all my *.cpp files. The problem is that now whenever I build I get a stream of linker errors: LNK2005: KeTimeStampBundle already defined in stdafx.obj. This should not be happening since the header file is only included in one file and is protected with include guards. The errors stop once I comment out the whole extern "C" block so I know that is what is causing the issue.
What's even stranger is when I add all these source files to a new project it builds without any problems. I don't see what the issue is here, can anyone enlighten me?
My IDE is Visual Studio 2008.
DWORD* KeTimeStampBundle;
This does not declare a function. It declares and defines an object of type DWORD* named KeTimeStampBundle. If you include this header file in multiple source files, you will have multiple definitions of this object (one from each source file in which the header is included).
Include guards and #pragma once ensure that something is only defined once in a given translation unit (source file). They have no effect on how things are defined across multiple translation units.
#pragma once doesn't keep your file from being included multiple times in the project, it keeps it from being included multiple times in the same file. So a.cpp and b.cpp can include the file once, and that defines KeTimeStampBundle twice.
To fix this, put the definition of KeTimeStampBundle and KeGetCurrentProcessType, etc. into a .cpp file and put extern DWORD* KeTimeStampBundle, etc in the header.
Note that this only applies to definitions, not declarations. extern ... and function prototypes are declarations, so they can be done multiple times, but definitions can only occur once in the entire project, accross all .cpp files.
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.
*note: I am new to c++, so sorry if I make an obvious mistake.
I am getting an error on all of my variables. I am trying to use headers and forward declarations. Here is a snippet of my code:
//BotRenderer.h
#ifndef BOTRENDERER_H_
#define BOTRENDERER_H_
#include <SDL2/SDL.h>
SDL_Texture *botTextures[217];
int currentBotFrame;
//BotRenderer.cpp
#include "BotRenderer.h"
SDL_Texture *botTextures[217];
int currentBotFrame = 0;
All of the lines with variables give the error, '[variable name here] previously declared here'. What can I do to fix this?
The problem is that include guards only protect against multiple inclusion in the same translation unit (source file).
If you define a variable in a header file and include it in more than one source file then the variable will be defined in both source files (translation units), and when you then link the generated object files together the linker will notice that the variable is defined in both object files and give you an error.
What you should do is declare the variables in the header file, the easiest to do it is to add the extern keyword before the declaration, like
extern SDL_Texture *botTextures[217];
extern int currentBotFrame;
Regarding your compiler error, you get it just because you define the variables in both the header file and in the source file. The solution you your problem is the same, declare in header file and define in source file.
You should read about the One Definition Rule (a.k.a. ODR).
I have always seen people write
class.h
#ifndef CLASS_H
#define CLASS_H
//blah blah blah
#endif
The question is, why don't they also do that for the .cpp file that contain definitions for class functions?
Let's say I have main.cpp, and main.cpp includes class.h. The class.h file does not include anything, so how does main.cpp know what is in the class.cpp?
First, to address your first inquiry:
When you see this in .h file:
#ifndef FILE_H
#define FILE_H
/* ... Declarations etc here ... */
#endif
This is a preprocessor technique of preventing a header file from being included multiple times, which can be problematic for various reasons. During compilation of your project, each .cpp file (usually) is compiled. In simple terms, this means the compiler will take your .cpp file, open any files #included by it, concatenate them all into one massive text file, and then perform syntax analysis and finally it will convert it to some intermediate code, optimize/perform other tasks, and finally generate the assembly output for the target architecture. Because of this, if a file is #included multiple times under one .cpp file, the compiler will append its file contents twice, so if there are definitions within that file, you will get a compiler error telling you that you redefined a variable. When the file is processed by the preprocessor step in the compilation process, the first time its contents are reached the first two lines will check if FILE_H has been defined for the preprocessor. If not, it will define FILE_H and continue processing the code between it and the #endif directive. The next time that file's contents are seen by the preprocessor, the check against FILE_H will be false, so it will immediately scan down to the #endif and continue after it. This prevents redefinition errors.
And to address your second concern:
In C++ programming as a general practice we separate development into two file types. One is with an extension of .h and we call this a "header file." They usually provide a declaration of functions, classes, structs, global variables, typedefs, preprocessing macros and definitions, etc. Basically, they just provide you with information about your code. Then we have the .cpp extension which we call a "code file." This will provide definitions for those functions, class members, any struct members that need definitions, global variables, etc. So the .h file declares code, and the .cpp file implements that declaration. For this reason, we generally during compilation compile each .cpp file into an object and then link those objects (because you almost never see one .cpp file include another .cpp file).
How these externals are resolved is a job for the linker. When your compiler processes main.cpp, it gets declarations for the code in class.cpp by including class.h. It only needs to know what these functions or variables look like (which is what a declaration gives you). So it compiles your main.cpp file into some object file (call it main.obj). Similarly, class.cpp is compiled into a class.obj file. To produce the final executable, a linker is invoked to link those two object files together. For any unresolved external variables or functions, the compiler will place a stub where the access happens. The linker will then take this stub and look for the code or variable in another listed object file, and if it's found, it combines the code from the two object files into an output file and replaces the stub with the final location of the function or variable. This way, your code in main.cpp can call functions and use variables in class.cpp IF AND ONLY IF THEY ARE DECLARED IN class.h.
I hope this was helpful.
The CLASS_H is an include guard; it's used to avoid the same header file being included multiple times (via different routes) within the same CPP file (or, more accurately, the same translation unit), which would lead to multiple-definition errors.
Include guards aren't needed on CPP files because, by definition, the contents of the CPP file are only read once.
You seem to have interpreted the include guards as having the same function as import statements in other languages (such as Java); that's not the case, however. The #include itself is roughly equivalent to the import in other languages.
It doesn't - at least during the compilation phase.
The translation of a c++ program from source code to machine code is performed in three phases:
Preprocessing - The Preprocessor parses all source code for lines beginning with # and executes the directives. In your case, the contents of your file class.h is inserted in place of the line #include "class.h. Since you might be includein your header file in several places, the #ifndef clauses avoid duplicate declaration-errors, since the preprocessor directive is undefined only the first time the header file is included.
Compilation - The Compiler does now translate all preprocessed source code files to binary object files.
Linking - The Linker links (hence the name) together the object files. A reference to your class or one of its methods (which should be declared in class.h and defined in class.cpp) is resolved to the respective offset in one of the object files. I write 'one of your object files' since your class does not need to be defined in a file named class.cpp, it might be in a library which is linked to your project.
In summary, the declarations can be shared through a header file, while the mapping of declarations to definitions is done by the linker.
That's the distinction between declaration and definition. Header files typically include just the declaration, and the source file contains the definition.
In order to use something you only need to know it's declaration not it's definition. Only the linker needs to know the definition.
So this is why you will include a header file inside one or more source files but you won't include a source file inside another.
Also you mean #include and not import.
That's done for header files so that the contents only appear once in each preprocessed source file, even if it's included more than once (usually because it's included from other header files). The first time it's included, the symbol CLASS_H (known as an include guard) hasn't been defined yet, so all the contents of the file are included. Doing this defines the symbol, so if it's included again, the contents of the file (inside the #ifndef/#endif block) are skipped.
There's no need to do this for the source file itself since (normally) that's not included by any other files.
For your last question, class.h should contain the definition of the class, and declarations of all its members, associated functions, and whatever else, so that any file that includes it has enough information to use the class. The implementations of the functions can go in a separate source file; you only need the declarations to call them.
main.cpp doesn't have to know what is in class.cpp. It just has to know the declarations of the functions/classes that it goes to use, and these declarations are in class.h.
The linker links between the places where the functions/classes declared in class.h are used and their implementations in class.cpp
.cpp files are not included (using #include) into other files. Therefore they don't need include guarding. Main.cpp will know the names and signatures of the class that you have implemented in class.cpp only because you have specified all that in class.h - this is the purpose of a header file. (It is up to you to make sure that class.h accurately describes the code you implement in class.cpp.) The executable code in class.cpp will be made available to the executable code in main.cpp thanks to the efforts of the linker.
It is generally expected that modules of code such as .cpp files are compiled once and linked to in multiple projects, to avoid unnecessary repetitive compilation of logic. For example, g++ -o class.cpp would produce class.o which you could then link from multiple projects to using g++ main.cpp class.o.
We could use #include as our linker, as you seem to be implying, but that would just be silly when we know how to link properly using our compiler with less keystrokes and less wasteful repetition of compilation, rather than our code with more keystrokes and more wasteful repetition of compilation...
The header files are still required to be included into each of the multiple projects, however, because this provides the interface for each module. Without these headers the compiler wouldn't know about any of the symbols introduced by the .o files.
It is important to realise that the header files are what introduce the definitions of symbols for those modules; once that is realised then it makes sense that multiple inclusions could cause redefinitions of symbols (which causes errors), so we use include guards to prevent such redefinitions.
its because of Headerfiles define what the class contains (Members, data-structures) and cpp files implement it.
And of course, the main reason for this is that you could include one .h File multiple times in other .h files, but this would result in multiple definitions of a class, which is invalid.
In an .h file, I am declaring a global variable as:
#pragma data_seg(".shared")
#ifndef DEF_VARX
#define DEF_VARX
int VARX=0;
#endif /*DEF_VARX*/
#pragma data_seg()
#pragma comment(linker, "/SECTION:.shared,RWS")
However if I include this file in multiple cpp files, when I try to compile, I get " error LNK2005: "int VARX" (?VARX##3HA) already defined in Dll.obj" error. If I include in only one cpp file, no problem is encountered.
Isn't #IFNDEF.... check enough for preventing this? Am I missin something?
The reason of this behavior is, that you compile the line
int VARX=0;
into each .obj file. Thats OK for compiling, but upon linking the symbol becomes multiply defined, which is illegal. Using
extern int VARX;
in the header file, and
int VARX=0;
in one (and only one) source file resolves this problem.
I think you're supposed to forward declare the variable in the .h and later define it in its shared section in a .cpp, something like:
// in a header file
#pragma once
extern int VARX;
// in a .cpp
#pragma data_seg(".shared")
int VARX=0;
#pragma data_seg()
#pragma comment(linker, "/SECTION:.shared,RWS")
The problem is that is that you prevent multiple inclusion of the file for a given translation unit. (for a given say cpp file)
But if several of your cpp include this VARX.H, then you'll have more than one definition for this variable.
Instead, you should only declare the variable in the .H file, but initialize it to 0 in only one location.
Yes, you're missing the extern keyword.
In your header file, use:
extern int VARX;
In a source file, actually declare space for the variable:
int VARX = 0;
ifdef prevents it for a separe object file. When the header is include in several source (cpp) files, VARX will be dedfined in all of them. Consider declaring it as extern in header file, and initialize in one cpp file.
The problem is you must be including the file in multiple compilation units. Let's say you have a.cpp and b.cpp. Both include your header file. So the compiler will compile (and pre-process) separately, so for both files, DEF_VARX is not yet defined. When you go to link the to object files together, the linker notices that there is a name collision.
As others have suggested, the solution would be to declare it 'extern', then place the actual value in a cpp file, so it only is compiled once, and linked to everything without name collisions.