I think you missed something.
static function?
Declaring a static function will make it “hidden” in its compilation unit.
A name that has a namespace scope (3.3.6) has an internal relationship if that name
- a template for a variable, function, or function that is explicitly declared static;
3.5 / 3 - C ++ 14 (n3797)
If the name has an internal relationship, the designated object may refer to names from other areas in the same translation unit.
3.5 / 2 - C ++ 14 (n3797)
If you declare this static function in the header, then all compilation units, including this header, will have their own copy of the function.
The fact is that there are static variables in this function, each compilation unit, including this header, will also have its own personal version.
built-in function?
Declaring it inline makes it a candidate for inlining (currently this does not mean that there is a lot in C ++, since the compiler will be built-in or not, sometimes ignoring the presence or absence of the inline keyword):
A function declaration (8.3.5, 9.3, 11.3) with a built-in specifier declares a built-in function. The inline specifier indicates the implementation that the built-in substitution of the function body at the call point is preferable to the usual function call mechanism. An implementation is not required to perform this built-in lookup at the dial peer; however, even if this built-in substitution is omitted, other rules for the built-in functions defined in 7.1.2 must still be followed.
7.1.2 / 2 - C ++ 14 (n3797)
It has an interesting side effect in the header: the built-in function can be defined several times in one module, and the linker simply attaches "them" to one (if they were not included for the reason for the compiler).
For static variables declared internally, the standard specifically says there one and only one of them:
A static local variable in an external inline function always refers to the same object.
7.1.2 / 4 - C ++ 98 / C ++ 14 (n3797)
(the default functions are external, so if you do not specifically mark your function as static, this applies to this function)
This has the advantage of “static” (that is, it can be defined in the header) without its drawbacks (it exists no more than once if it is not built-in)
static local variable?
Static local variables have no binding (they cannot be specified by name outside their scope), but they have a static storage duration (i.e. global, but its construction and destruction are subject to certain rules).
static + inline?
Mixing inline and static will have the consequences that you described (even if the function is enabled, the static variable will not be inside, and you will end up with the same static variables as you have compilation units, including defining your static functions).
Answer the author an additional question
Since I wrote the question, I tried it with Visual Studio 2008. I tried to include all the options that make VS act according to the standards, but it is possible that I missed some of them. Here are the results:
When a function is simply “inline”, there is only one copy of the static variable.
When a function is “static inline”, there are as many copies as translation units.
The real question is whether this should be so, or if it is the idiosyncrasy of the Microsoft C ++ compiler.
So you have something like this:
void doSomething() { static int value ; }
You should understand that a static variable is inside a function, just set a global variable hidden for everyone except the function area, which means that only the function that it declared inside can come to it.
Embedding a function will not change anything:
inline void doSomething() { static int value ; }
There will be only one hidden global variable. The fact that the compiler will try to embed the code will not change the fact that there is only one global hidden variable.
Now, if your function is declared static:
static void doSomething() { static int value ; }
Then for each compilation unit it is "private", which means that each CPP file, including the header in which the static function is declared, will have its own private copy of the function, including its own private copy of the global hidden variable, such as many variables as there are compilation units, including a header.
Adding an "inline" to a "static" function with a "static" variable inside:
inline static void doSomething() { static int value ; }
has the same result as not adding this inline keyword as far as a static variable is concerned.
So, the behavior of VC ++ is correct, and you accept the real meaning of "inline" and "static".