Static variables in a built-in function

I have a function that is declared and defined in the header file. This is a problem in itself. When this function is not enabled, each translation unit that uses this header receives a copy of the function, and when they are connected to each other, are duplicated. I "fixed" this by making the inline function, but I'm afraid this is a fragile solution, because as far as I know, the compiler does not guarantee attachments, even if you specify the keyword "inline". If this is not correct, please correct me.

In any case, the real question is: what happens to static variables inside this function? How many copies do I get?

+52
c ++ linker header inline-functions
Oct 09 '08 at 1:43
source share
9 answers

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".

+78
09 Oct '08 at 20:51
source share

I believe that the compiler creates many copies of the variable, but the linker selects one, and the rest refer to it. I had similar results when I tried an experiment to create different versions of an inline function; if the function was not actually built-in (debug mode), all calls passed to the same function regardless of the source file from which they were called.

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; therefore, everyone should create a copy of the variable, considering it the only one. The linker has the ability to reach these boundaries and adjust the links for both variables and functions.

+28
Oct 09 '08 at 2:35
source share

I found Mark Ransom's answer useful - that the compiler creates many copies of the static variable, but the linker selects one and applies it to all translation units.

Elsewhere, I found this:

See [dcl.fct.spec] / 4

[..] The built-in function with external communication must have the same address in all translation units. A static local variable in an external inline function always refers to the same object. A string literal in an external built-in function is the same object in different translation units.

I do not have a copy of the standard for verification, but it matches my experience when considering building in VS Express 2008

+7
05 Sep '09 at 22:27
source share

This is supposed to be so. "static" tells the compiler that you want the function to be local to the compilation unit, so you want one copy per compilation unit and one copy of static variables per function instance.

"inline" is used to tell the compiler that you want the function to be inline; at present, he simply perceives this as "it is normal if there are several copies of the code, just make sure that it is one and the same function." Thus, everyone shares static variables.

Note: This answer was written in response to the answer of the original poster published for myself.

+5
Oct 09 '08 at 2:33
source share

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 the case, or if it's ideosynchronization of the Microsoft C ++ compiler.

+3
Oct 09 '08 at 2:19
source share

I believe that you will have one translation unit. In fact, you got many versions of this function (and its declared static variable), one for each translation unit containing the header.

0
Oct 09 '08 at 1:47
source share

An attachment means that the executable code (instructions) is embedded in the code of the calling function. The compiler can do this regardless of whether you ask. This does not affect the variables (data) declared in the function.

0
Oct 09 '08 at 1:51
source share

Besides any design problems that all of this can mean, since you are already stuck with it, you should use static in this case not built-in. Thus, all have the same variables. (Static function)

0
Oct 09 '08 at 2:15
source share

Static means that one copy is distributed throughout the program, but the built-in means that it needs the same code for several times in the same program, so it is impossible to make the static variable inside the built-in function.

-one
Aug 29 '09 at 2:34
source share



All Articles