Reputation: 77
In my C++ project ,when i declare a global variable in my header file,i get LNK2005(x is already defined in y.obj) and LNK1169(one or more multiply defined symbols found z.exe) errors in visual studio 2012,but when i declare the global variable with const identifier,i do not get an error.From my research in msdn i understand that it is because of project properties.But i can not fix them with properties.It is only fixed with const identifier.But i can not find any rules about it in C++.is it a new feature in C++11???
Upvotes: 2
Views: 2203
Reputation: 400274
This is a declaration of a global variable:
extern int my_global;
Thie is a definition of a global variable:
int my_global;
A declaration of a global variable says "here is the name of an object". A definition says "here is the name of an object, and please allocate storage space for it".
You can have as many declarations of a global variable as you want (so that anyone in any source file can refer to that same object), but you can only have one definition, since the object can only exist in one place in memory when the program runs.
The linker is complaining that you have multiple definitions of the same object because you're putting a definition in the header file, and that header gets included in multiple source files. So when, those source files get compiled, you get multiple definitions, and the linker can't do that.
The solution is to put only a declaration in the header file, and then put the definition in exactly one source file. For example:
// MyVariables.h
extern int my_global;
// MyVariables.cpp
int my_global = 42;
The reason you're seeing different behavior with the const
keyword is because the const
gives global variables internal linkage, meaning they're not visible to other source files. In effect, these means that each source file that includes your header gets its own copy of the constant. This takes up a little more memory, but it's not going to be noticeable. And since it's a constant, nobody's going to notice that the different constants refer to different locations in memory.
C++11 did not change any of this behavior. These constructs all behaved the same way in previous versions of C++.
Upvotes: 5