I have a function that is declared and defined in a header file. This is a problem all by itself. When that function is not inlined, every translation unit that uses that header gets a copy of the function, and when they are linked together there are duplicated. I "fixed" that by making the function inline, but I'm afraid that this is a fragile solution because as far as I know, the compiler doesn't guarantee inlining, even when you specify the "inline" keyword. If this is not true, please correct me.
Anyways, the real question is, what happens to static variables inside this function? How many copies do I end up with?
I believe the compiler creates many copies of the variable, but the linker picks one and makes all the others reference it. I had similar results when I tried an experiment to create different versions of an inline function; if the function wasn't actually inlined (debug mode), all calls went to the same function regardless of the source file they were called from.
Think like a compiler for a moment - how could it be otherwise? Each compilation unit (source file) is independent of the others, and can be compiled separately; each one must therefore create a copy of the variable, thinking it is the only one. The linker has the ability to reach across those boundaries and adjust the references for both variables and functions.
I believe you will end up with one per translation unit. You've effectively got many versions of that function (and its declared static variable), one for every translation unit that includes the header.
It is supposed to be this way. "static" tells the compiler you want the function to be local to the compilation unit, therefore you want one copy per compilation unit and one copy of the static variables per instance of the function.
"inline" used to tell the compiler you want the function to be inlined; nowadays, it just takes it as "it's ok if there are several copies of the code, just make sure it's the same function". So everybody shares the static variables.
Note: this answer was written in response to the answer the original poster posted to himself.
I guess you're missing something, here.
static function?
Declaring a function static will make it "hidden" in its compilation unit.
If you declare this static function in a header, then all the compilation units including this header will have their own copy of the function.
The thing is, if there are static variables inside that function, each compilation unit including this header will also have their own, personal version.
inline function?
Declaring it inline makes it a candidate for inlining (it does not mean a lot nowadays in C++, as the compiler will inline or not, sometimes ignoring the fact the keyword inline is present or absent):
In a header, its has an interesting side effect: The inlined function can be defined multiple times in the same module, and the linker will simply join "them" into one (if they were not inlined for compiler's reason).
For static variables declared inside, the standard specifically says there one, and only one of them:
(functions are by default extern, so, unless you specifically mark your function as static, this applies to that function)
This has the advantage of "static" (i.e. it can be defined in a header) without its flaws (it exists at most once if it is not inlined)
static local variable?
Static local variables have no linkage (they can't be referred to by name outside their scope), but has static storage duration (i.e. it is global, but its construction and destruction obey to specific rules).
static + inline?
Mixing inline and static will then have the consequences you described (even if the function is inlined, the static variable inside won't be, and you'll end with as much static variables as you have compilation units including the definition of your static functions).
Answer to author's additional question
So I suppose you have something like that:
You must realise that the static variable inside the function, simply put, a global variable hidden to all but the function's scope, meaning that only the function it is declared inside can reach it.
Inlining the function won't change anything:
There will be only one hidden global variable. The fact the compiler will try to inline the code won't change the fact there is only one global hidden variable.
Now, if your function is declared static:
Then it is "private" for each compilation unit, meaning that every CPP file including the header where the static function is declared will have its own private copy of the function, including its own private copy of global hidden variable, thus as much variables as there are compilation units including the header.
Adding "inline" to a "static" function with a "static" variable inside:
has the same result than not adding this "inline" keyword, as far as the static variable inside is concerned.
So the behaviour of VC++ is correct, and you are mistaking the real meaning of "inline" and "static".
I found Mark Ransom's answer helpful - that the compiler creates many copies of the static variable, but the linker chooses one and enforces it across all translation units.
Elsewhere I found this:
See [dcl.fct.spec]/4
I don't have a copy of the standard to check, but it matches with my experience examining the assembly in VS Express 2008
Static means one copy is distributed throughout the program , but inline means it requires the same code for several time in the same program , so it is not possible to make a variable static inside the inline function.