*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).
Related
I am wondering if it is possible to both declare and define an extern variable in the same header file. I need the variable to be referenced across multiple files, and while I realize there are better ways to achieve this, using extern is the only option in this case. So is it possible to do:
// in main.h
extern int foo;
int foo;
etc...
And then any file which includes main.h will have access to foo? Many examples reference defining the extern'd variable in a separate cpp file, but I'm just wondering if the way I suggested will cause problems across the rest of the project.
If you put a definition in a header file, you will end up with multiple definitions when multiple source files are involved.
For example, suppose both main.c and other.c include foo.h. When you compile each of these files you'll get main.o and other.o, both of which have a definition of int foo. If you then attempt to link main.o and other.o into a single executable, you'll get a linker error stating that int foo was defined twice.
To do this properly, you declare your variable in the header file as extern int foo. Then, in one (and only one) source file you define the variable with int foo.
Real definitions (not extern) should not be in a header file.
If you want to have one global variable available from different cpp, you should make two things: definition in one cpp and extern declaration in h.
E.g.:
// global.h
extern int foo;
and
// global.cpp
int foo;
Then in any file where foo is needed:
#include "global.h"
And, of course, global.cpp have to be part of project (compiled with other files)
What you are doing is perfectly legal in C++ only if there aren't multiple files which are defining the same variable.
The variable or function may be defined in another source file, or
later in the same file. Declarations of variables and functions at
file scope are external by default.
Normally we extern a global variable declared in some other file.
This is as good as a global variable initialized to 0.
I am including a .h file with a global boost signal in a the header file of a class which is, in turn included in the main function's file. The linker says the signal is declare multiple times. The signal declaration is wrapped in the #ifndef, #define and #endif block typical of C/C++ header files (used to avoid multiple declaration).
I am using Eclipse with gcc.
#ifndef SIG_HEADER
#define SIG_HEADER
#include <boost/signal.hpp>
boost::signal0 <void> signal1;
#endif
what am I doing wrong?
You're getting a linker error, not a compiler error. So, preprocessor directives won't help you here.
What you need to do is define the variable inside the source file (as opposed to the header file), and use an extern declaration in the header file.
Your linker is correct. Each time you include this header the symbol signal1 gets defined, resulting in a multiple definition error.
To your rescue comes the extern keyword, which will tell the compiler that this is an object that will be accessed by the entire program and requires external linkage. You will then have to give the compiler a definition of the variable somewhere else, like in the cpp file for this header.
This question offers some more information about external linkage.
I am getting error messages from the mbed C++ compiler that seem to be indicative of malfunctioning include guards.
In main.cpp, I include my header file as follows:
#include "mbed.h"
#include "sample.h"
This is my sample.h:
#include "mbed.h"
#ifndef STUFF_H
#define STUFF_H
/* LEDs */
DigitalOut led1(LED1);
DigitalOut led2(LED2);
DigitalOut led3(LED3);
DigitalOut led4(LED4);
/* Subroutines */
void sweepLEDs();
void pulseLEDs(int numPulses);
void clearLEDs();
#endif
In sample.cpp, I am including sample.h as follows:
#include "sample.h"
In both main.cpp and sample.cpp, I am referring to variables led1, led2, led3, led4 without declaring them. However, the compiler is outputting these complaints:
" Symbol led1 multiply defined (by sample.cpp.cpp.LPC1768.o and main.cpp.cpp.LPC1768.o)."
...
" Symbol led4 multiply defined (by sample.cpp.cpp.LPC1768.o and main.cpp.cpp.LPC1768.o)."
Are my include guards written improperly? Or is there some other issue?
(For reference, here is the link to the mbed.h source)
The issue is a misunderstanding of what include guards do. Include guards prevent the compiler from seeing the same content again in the same translation unit (for the same .cpp file). They do not prevent separate translation units from seeing the same code.
In your header file, you define (not just declare) the variables. Therefore every translation unit which includes the header creates its own copy of those variables.
The correct way to do it is to define the variables in a .cpp file and only declare them in the header (the include guards should be there anyway, to prevent multiple inclusion in the same translation unit).
That is, in your file sample.h, prefix your variables with extern and remove the initializer (so they are only declared, not defined), and define them in the corresponding .cpp file (the one where also the functions are defined), by putting the exact definitions from your header there.
In an unrelated note, you should put the #include "mbed.h" in sample.h inside the include guards, because some compilers optimize compile speed for such guards, and that optimization doesn't work if there's material outside the include guards. Note that this is not really a correctness issue (assuming mbed.h is properly protected by include guards as well), but a compiling performance issue.
You need to mark the declarations as "extern" like this:
extern DigitalOut led1;
Then define them (i.e. allocate storage for them) in sample.cpp by using the expression you used to have in the header.
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.
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.