When I declared and initialized a const object.
// ConstClass.h
class ConstClass
{
};
const ConstClass g_Const;
And two cpp files include this header.
// Unit1.cpp
#include "ConstClass.h"
#include "stdio.h"
void PrintInUnit1( )
{
printf( "g_Const in Unit1 is %d.\r\n", &g_Const );
}
and
// Unit2.cpp
#include "ConstClass.h"
#include "stdio.h"
void PrintInUnit2( )
{
printf( "g_Const in Unit2 is %d.\r\n", &g_Const );
}
When i build the solution, there was no link error, what you will get If g_Const is a non-const fundamental type!
And PrintInUnit1() and PrintInUnit2() show that there are two independent "g_Const"s with different address in two compilation units, Why?
==============
I know how to fix it.(use extern keyword to declaration, and define it in one cpp file.)
I wonder to know why I did't get redfined link error in this sample.
https://stackoverflow.com/a/6173889/1508519
const variable at namespace scope has internal linkage. So they're basically two different variables. There is no redefinition.
3.5/3 [basic.link]:
A name having namespace scope (3.3.5) has internal linkage if it is the name of
— an object, reference, function or function template that is explicitly declared static or,
— an object or reference that is explicitly declared const and neither explicitly declared extern nor previously declared to have external linkage; or
— a data member of an anonymous union.
Use extern
if you want it to have external linkage.
As stated in the other answer, header files are just pasted in cpp files. The same header file is included in both cpp files, but they are separate translation units. That means that one instance of a variable is different from the other instance. In other to let the compiler know that you have defined the variable elsewhere, use the extern
keyword. This ensures only one instance is shared across translation units. However extern const Test test
is just a declaration. You need a definition. It doesn't matter where you define it as long as it is defined once in some cpp file. You can declare it as many times as you want (which is convenient for placing it in a header file.)
So for example:
Constant.h
class Test
{
};
extern const Test test;
Unit1.cpp
#include "Constant.h"
#include <iostream>
void print_one()
{ std::cout << &test << std::endl; }
Unit2.cpp
#include "Constant.h"
#include <iostream>
void print_two()
{ std::cout << &test << std::endl; }
main.cpp
extern void print_one();
extern void print_two();
int main()
{
print_one();
print_two();
}
Constant.cpp
#include "Constant.h"
const Test test = Test();
Makefile
.PHONY: all
all:
g++ -std=c++11 -o test Constant.cpp Unit1.cpp Unit2.cpp main.cpp