How does the compiler know to call function once per static variable?
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).
精彩评论