开发者

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

开发者 https://www.devze.com 2022-12-29 23:41 出处:网络
E.g 开发者_开发问答 foo1() { static const char* str = foo2(); } const char * foo2 () { ... } How does the compiler makes sure it calls foo2 just once.foo2 is called at the initialisation of

E.g

开发者_开发问答
 foo1() {
     static const char* str = foo2();

 }

 const char * foo2 () {

     ...
 }

How does the compiler makes sure it calls foo2 just once.


foo2 is called at the initialisation of your program, just before main().

Edit: this is wrong! I assumed this as this is how normally static initialisation works. But in this case, they are called once at the start of the function.

It must work with some kind of static boolean. Yep. At least in gcc, this:

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

Compiles to:

 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    

So it uses a hidden, function specific boolean (at $0x804a030) + some magic to protect against exceptions and multiple threads calling it at once.


There isn't one compiler. gcc might do this one way, visual studio might do it another.

Conceptually, there is a hidden static boolean, and the compiler is generating an if statement.


A static in a function is called the first time it is hit. For example:

#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 this:

calling foo:
initializing thing
done
foo returned
calling foo:
done
foo returned


A compiler might 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 the initialization of __str_initialized can occur as a normal part of initializing the data segment to 0, so nothing special needs to happen there.

Also note that this is not thread-safe, and generally speaking the static variable initialization that compilers perform will not be thread safe (nor is it required to beby the standard - I'm not sure what compilers might make this thread-safe).

0

精彩评论

暂无评论...
验证码 换一张
取 消