I am testing static member variables on Windows using Visual Studio 2015. The project comprises three .cpp and one header:
StaticHeader.h:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
|
#pragma once
#include <iostream>
template <typename T>
class TempClass {
public:
static T m_Static;
static void Inc() {
m_Static++;
}
static void Dec() {
m_Static--;
}
static void StaticFunc();
static void showStatic();
};
template <typename T>
void TempClass<T>::showStatic() {
std::cout << "###" << m_Static;
}
|
StaticCpp1.cpp:
1 2 3 4 5 6 7 8 9 10
|
#include "StaticHeader.h"
template <typename T>
T TempClass<T>::m_Static = 1;
template <class T> void TempClass<T>::StaticFunc() {
Inc();
}
template class TempClass<float>;
|
StaticCpp2.cpp:
1 2 3 4 5 6 7 8 9 10
|
#include "StaticHeader.h"
template <typename T>
T TempClass<T>::m_Static = 100;
template <class T> void TempClass<T>::StaticFunc() {
Dec();
}
template class TempClass<float>;
|
Main.cpp:
1 2 3 4 5 6 7 8 9
|
#include "StaticHeader.h"
template <typename T>
T TempClass<T>::m_Static = 4.5;
int main() {
TempClass<float>::StaticFunc();
TempClass<float>::showStatic();
}
|
The above code can be compiled and linked in VS2015. I then use the debugger to trace the code and found that the statement TempClass<float>::StaticFunc(); always goes into the StaticFunc() function in StaticCpp1.cpp. So my first question is:
(1) When the two source file StaticCpp1.cpp and StaticCpp2.cpp are essentially the same, why does the compiler choose the former over the latter?
Then I removed the m_Static definition in both Main.cpp and StaticCpp1.cpp. The program still goes into StaticCpp1.cpp, but print out 101, showing that it is the static variable defined in StaticCpp2.cpp that is used. So my second question is:
(2) By default, if we defined a normal (not a member of a class) static variable , it has only internal linkage, meaning that it can be seen only in the .cpp source file defining it. Based on this rule, StaticCpp1.cpp should not be able to see the static variable defined in StaticCpp2.cpp. But why is StaticCpp1.cpp able to see it in StaticCpp2.cpp? Is global linkage the default for static member?
And my third question is:
(3) With the original code, is the static member variable unique, i.e., there is only one copy of TempClass<T>::m_Static in memory? Or there is one for each .cpp?
To avoid mess, I am talking about Visual Studio 2015 on Windows 10 version 1803.
Thank you.