Reputation: 3658
I have two files as below:
Test1.h
#ifndef TEST_H
#define TEST_H
int i = 10;
#endif
Test2.cpp
#include <iostream>
#include "Test1.h"
int main()
{
std::cout << i << std::endl;
}
I know I can solve this by using extern or const in Test1.h
.
But my question is that "I don't understand the error".
error LNK2005: "int i" (?i@@3HA) already defined in Test1.obj
error LNK1169: one or more multiply defined symbols found
How can int i
have multiple definitions?
Test2.cpp
and it should become:Test2.cpp
#include <iostream>
int i = 10
int main()
{
std::cout << i << std::endl;
}
And header file should become irrelevant at this point after everything being included.
My other question is if I declare int i
with extern
in header file and include it in .cpp, then would it be an example of external linkage? Because generally I have seen external linkage between two .c
or .cpp
as in here but if you explicitly include the file is it still regarded as i
having external linkage?
Upvotes: 1
Views: 309
Reputation: 6103
Do you have other Test1.cpp in your project that also include the Test1.h ?
If not, do you do any config to your compiler so it also build the .h files to object files ?
The reason can just be the answer of one of two questions above.
Upvotes: 0
Reputation: 238321
How can int i have multiple definitions?
The file that has the definition was included in multiple translation units (cpp file). One unit was compiled into the object file Test1.obj
. The source of the other unit is shown in your answer (Test2.cpp
). The error is shown when you try to link the object files together.
- The header file has include guards.
That prevents the contents of the file from being repeated within a single translation unit. It makes no difference to separate units.
My other question is if I declare int i with extern in header file and include it in .cpp, then would it be an example of external linkage?
extern
makes the linkage external explicitly. But even without extern
, variables declared in the namespace scope have implicit external linkage by default (there are exceptions). The difference in this case is that extern
variable declarations are not definitions unless there is an initializer.
I can achieve external linkage without including header file i.e. with two .cpp files by making a variable extern in one .cpp and defining it in other and linker finds its definition. But if I have one header file with extern variable and include it in other .cpp does this count as external linkage?
It does not matter how the extern declaration ends up in the cpp file. Whether it was included from a header or not, it declares a variable with external linkage.
Upvotes: 1
Reputation: 385144
When I include the header file it should mean that everything gets copied in Test2.cpp and it should become:
Yes and then you do the exact same thing in Test1.cpp (which you didn't show us).
Hence, multiple definitions.
Upvotes: -1
Reputation: 31435
Each compilation unit (a .cpp file) produces its own set of symbols individually which are then linked together by the linker.
A header file "becomes" part of the compilation unit it is included in, which compile to an object file (.obj in Windows, .o in Unix systems)
Therefore it is like you have defined a global 'i' in each compilation unit. The correct solution (as you know, if you have to have a global) is to declare it as "extern" in the header then have one compilation unit actually define it.
Include guards only prevent the same header being included twice in the same compilation unit, which can happen if I include and and one of those includes the other.
Upvotes: 3
Reputation: 831
Probably you are trying to create the executable file from two unit of translations.
Your error shows that the object have been defined in Test1.obj. Probably, your program is Test1.obj+Test2.obj, and both files include the same definition, which has external linkage.
Upvotes: 1