Let's see on case by case basis what is happening:
Case 1
Here we consider:
a.cpp
namespace pers{
const int LEN = 5; //this LEN has internal linkage and is different from the LEN defined in b.cpp
}
b.cpp
namespace pers {
const int LEN = 5; //this LEN has internal linkage and is different from the LEN defined in a.cpp
}
int main() {
return 0;
}
It can be compiled successfully.But I dont know why?
This is because LEN
has internal linkage meaning its use is limited to a single translation unit and so the LEN
in a.cpp and b.cpp are not the same. This can be see from basic.link which states:
A name having namespace scope has internal linkage if it is the name of
- a non-inline variable of non-volatile const-qualified type that is neither explicitly declared extern nor previously declared to have external linkage; or
And also,
When a name has internal linkage, the entity it denotes can be referred to by names from other scopes in the same translation unit.
(emphasis mine)
This means the LEN
In a.cpp
and the LEN
in b.cpp
are distinct from each other and so there is no multiple definition error.
I defined LEN twice!!
As explained above, you're not defining the same LEN
twice. They are different from each other because they have a namespace scope and are const
qualified.
Case 2
Here we consider:
a.cpp
namespace pers{
int LEN = 5; //this LEN has external linkage and is the same a the LEN in b.cpp
}
b.cpp
namespace pers {
int LEN = 5; //this LEN has external linkage and is the same LEN as in a.cpp
}
int main() {
return 0;
}
In this case, LEN
has external linkage meaning both the LEN
in a.cpp and b.cpp are the same and since you're defining the same name twice, you're violating ODR.
Case 3
Here we consider:
namespace pers {
const int LEN = 5; //OK, define `LEN` with internal linkage for the first time
const int LEN = 5; // error because you're defining the same LEN with internal linkage for the second time in the same TU
const int LEN2 = 10;
}
int main() {
const int a = 10; //define a for the first time in this TU
const int a = 10; // error because you're defining the same a for the second time in the same TU
return 0;
}
In this case 3, you're definining the same LEN
twice and hence getting the mentioned error. We cannot define any entity more than once in the same translation unit.