How can static local variable shared along different translation unit?
I know that "static" specifies internal linkage.
In case of "static" member function having same address in different translation units, each translation unit has a copy of the function, and linker picks one of the copies to be included in executable.
Then, in the scenario of two different translation includes 1 shared header, which has a class with static member function that increments static local variable, and each translation unit (cpp) calls the the static member function of the shared header, each translation unit will increment its own independent static local variable because static specifies internal linkage. For example,
Shared.h
#pragma once
class CShared
{
public:
static inline void Foo()
{
static int s_nCount = 0;
++s_nCount;
}
private:
CShared(){}
~CShared(){}
};
A.h
#pragma once
class A
{
public:
A(){}
~A(){}
void Foo();
};
A.cpp
#include "A.h"
#include "Shared.h"
void A::Foo()
{
CShared::Foo();
}
B.h
#pragma once
class B
{
public:
B(){}
~B(){}
void Foo();
};
B.cpp
#include "B.h"
#include "Shared.h"
void B::Foo()
{
CShared::Foo();
}
main.cpp
#include <iostream>
#include "A.h"
#include "B.h"
int main()
{
A a;
B b;
a.Foo();
b.Foo();
return 0;
}
The result is s_nCount becomes 2 when b.Foo(). Therefore, the static local variable is "shared", not each translation unit having its own copy of static local variable, along different translation unit. Doesn't this mean the static local variable is not internal linkage? Isn't "shared between different translation unit" and "internal linkage" is conflicting term?
Anyone who clarifies this will be truly appreciated.
[Update]
So far it seems,
| static | linkage |
|---|---|
| CShared::Foo | something other than internal linkage |
| s_nCount | external linkage (Mike Nakis, The Dreams Wind) or no linkage (Vlad from Moscow) |
According to Some programmer dude,
| static | linkage |
|---|---|
| CShared::Foo | no linkage (cppreference) |
| s_nCount | no linkage (cppreference) |
In my understanding, CShared::Foo belongs to "no linkage - local classes and their member functions" s_nCount belongs to "no linkage - variables that aren't explicitly declared extern (regardless of the static modifier)"
Can anyone conclude this?
[Update2]
| static | linkage |
|---|---|
| CShared::Foo | external linkage |
| s_nCount | no linkage |
About "static" meaning in front of member function
"Static class members have external linkage. Class member functions have external linkage."
About "static" meaning in front of "global" variable
About "static" meaning in front of "local" variable
In this member function declaration
the local variable
s_nCountdoes not have internal linkage. It is not a namespace variable. It is a local variable declared without the storage class specifierextern. It is a local variable that has static storage duration and no linkage. So the function has only one its local variable that is initialized only once and is changed in each call of the function.From the C++17 STandard (6.5 Program and linkage)
and (10.1.6 The inline specifier)
Here is an example of a variable declared in block scope that has internal linkage.
The program output is
So the variable
ndeclared in the global namespace with the storage class specifierstatichas internal linkage. The local variablendeclared in block scope of the functionfdenotes (refers to) the variablenwith internal linkage declared in the global namespace.