As the doc says (emphasis mine):
Any of the following names declared at namespace scope have internal linkage:
- non-volatile non-template non-inline const-qualified variables (including constexpr) that aren't declared extern and aren't previously declared to have external linkage;
So I'd expect const template variables to have external linkage. So I did a test:
// main.cpp
void other();
template<class T> T var = 1;
template<class T> const T constVar = 1;
int main() {
std::cout << var<int> << ' ' << constVar<int> << std::endl;
other();
}
// other.cpp
template<class T> T var = 2;
template<class T> const T constVar = 2;
void other() {
std::cout << var<int> << ' ' << constVar<int> << std::endl;
}
And the output is:
1 1
1 2
The second column is for constVar
, and it differs for different rows (printed from different translation units). This makes me think that it actually has internal linkage, despite being a template.
I understand that I do violate ODR, but only to understand what's happening.
So does constVar
actually have internal linkage? If yes, what does the highlighted fragment of the doc mean? If no, then what's happening, and why do we need this highlighted fragment?
C++14 N4296 §14.4
C++14 N4296 §3.2.6
Templates are implicitly inline i.e. have external linkage. What's happening = undefined behaviour. Compiler is not required to diagnose your code and might produce unexpected/inconsistent results.