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.
Related
Can anyone tell me how a static function created in header file can be invoked in other files, though static function which is not created in header file can't be invoked in other files. What exactly happens when we declare static functions in header file vs other cpp/c files.
The "file" is a more or less meaningless concept in C and C++ - what matters is the "translation unit".
Somewhat simplified, when you compile one source file, that's one translation unit.
The #include mechanism is extremely simple - it literally just includes the contents of a file at that point.
And static makes a name local to the translation unit; it can't be seen anywhere else.
So, say you have a header "H.h":
static something X;
and two source files,
A.cpp:
#include "H.h"
and B.cpp:
#include "H.h"
then after preprocessing, this is what the compiler sees:
A.cpp:
static something X;
and B.cpp:
static something X;
In other words, you have two somethings called "X", completely independent of each other, and neither translation unit can access the other's.
(This is a frequent source of bugs that can be very hard to find, in particular if the intent is to have a globally mutable variable. Don't make things static in headers.)
If you define static function in a header file it will be be visible in any source file which includes this header file. You will have as many copies of the static function as you have source files that include it. It will increase the program size. I would suggest only defining static inline functions in the header files.
It is a common misunderstanding in C. Beginner programmers think that the header file is a "library" but in the fact "#include" only textually replaces #include <file.h> with the context of file.h creating one source file which is compiled by the compiler.
Example:
https://godbolt.org/z/Y5s9fecP6
*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 am making a C++ project with the main.cpp which has main function, then a header file header.h and a cpp file program.cpp which has class methods in it. So I wanted to ask is there a way to declare a variable that i would use in main.cpp and methods could read it in program.cpp ?
Yes.
Look up the extern keyword in your C++ book.
Global variables are discouraged in general, but you can do this simply with the following in your header file:
extern my_global_type myGlobal;
you then define myGlobal in main.cpp as:
my_global_type myGlobal = \* some init value *\;
and simply use it in program.cpp by including the header with the above extern. You can make it a bit less global (but not get rid of all the problems) by putting myGlobal in a namespace.
I have the following two files:
foo.h
bar.cpp
In foo.h I decleare a variable extern.
Now, I would like to use the same variable in bar.cpp (after including foo.h).
Under VS2008 and VS2010 I get unresolved external symbol errors, while under Ubuntu with gcc the compilation is successfull.
(Namely, I'm trying to compile the following source code:http://www.fromdual.com/using-mysql-user-defined-functions-udf; foo.h refers to srv0srv.h and bar.cpp refers to the source code. All includes are in place, compilation is a success, linking falls)
What might the problem be?
The extern keyword indicates to the compiler that the variable following it is already declared somewhere else. It does not actually allocate space for the variable. If you want to create a global variable which you can use by including a header file (which is generally a bad idea, by the way), you can do it in the following manner.
In foo.h:
extern int myVar;
in foo.cpp:
int myVar;
myVar is now located in foo.cpp, but the extern statement in foo.h allows code in other files (such as bar.cpp) to access it by including foo.h.
When you use extern to declare a variable(a global variable in other source objects or files), you actually tell compiler to look for the variable's definition somewhere else. In this case, you need to provide another source file that defines int myVar.
Your variable has to have a reference somewhere in one of the source files. By the extern keyword you are only telling that "there is a variable" but linker has to know the location of it. While you are compiling the source, it will create references for variables etc. Linker will link according to these references. If you do not actually create a reference to a variable linker will not be able to find the reference, so it will give error. If you use extern you are saying that do not create a reference to this variable or any other thing here. But there has to be a reference to it at somewhere else.
The problem was, that the afformentioned symbol has to be exported (via dllspec) from the dll, to be visible from outside. Only the extern keyword did not allowed it to be seen from outside.
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.