How does the compiler know to call a function once for a static variable?

For instance,

foo1() { static const char* str = foo2(); } const char * foo2 () { ... } 

How the compiler makes sure that it calls foo2 only once.

+4
source share
4 answers

foo2 is called when you initialize your program immediately before main () .

Edit: this is wrong ! I assumed this since static initialization usually works. But in this case they are called once at the beginning of the function.

It should work with some kind of static boolean. Yeah. At least in gcc, this is:

 int test2() { static int bla = test(); } 

Compiles:

  8048616: b8 30 a0 04 08 mov $0x804a030,%eax 804861b: 0f b6 00 movzbl (%eax),%eax 804861e: 84 c0 test %al,%al 8048620: 75 52 jne 8048674 <_Z5test2v+0x67> ... 804863c: e8 b3 ff ff ff call 80485f4 <_Z4testv> ... 8048674: 83 c4 1c add $0x1c,%esp 8048677: 5b pop %ebx 8048678: 5e pop %esi 8048679: 5f pop %edi 804867a: 5d pop %ebp 804867b: c3 ret 

Thus, it uses a hidden, function-specific logical (in $ 0x804a030) + some magic to protect against exceptions and several threads that cause it at once.

+4
source

There is more than one compiler. gcc can do it one way; visual studio can do it the other.

It is clear that there is a hidden static logical expression, and the compiler generates an if statement.

+4
source

Staticity in a function is called first when it hits. For instance:

 #include <stdio.h> class Thing { public: Thing() { printf ("initializing thing\n"); } }; int foo() { static Thing *thing = new Thing; printf ("done\n"); } int main() { printf ("calling foo:\n"); foo(); printf ("foo returned\n"); printf ("calling foo:\n"); foo(); printf ("foo returned\n"); } 

Gives the following:

 calling foo: initializing thing done foo returned calling foo: done foo returned 
0
source

The compiler can compile the following:

 void foo1() { static const char* str = foo2(); } 

as if it were written as:

 void foo1() { static int __str_initialized = 0; static const char* str; if (__str_initialized == 0) { str = foo2(); __str_initialized = 1; } } 

Note that __str_initialized initialization can be performed as a normal part of initializing a data segment to 0, so there shouldn’t be anything special.

Also note that this is not thread safe, and generally speaking, static variable initialization performed by compilers will not be thread safe (and it doesn't have to be a standard - I'm not sure which compilers can make this thread safe).

0
source

Source: https://habr.com/ru/post/1309058/


All Articles