E.g
foo1() {
static const char* str = foo2();
}
const char * foo2 () {
...
}
编译器如何确保它只调用一次foo2。
答案 0 :(得分:4)
foo2在程序初始化时调用,就在main()之前。
编辑:这是错误!我认为这是正常静态初始化的工作方式。但在这种情况下,它们在函数开始时被调用一次。
它必须使用某种静态布尔值。是的。至少在gcc中,这个:
int test2()
{
static int bla = test();
}
编译为:
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
因此它使用隐藏的,函数特定的布尔值($ 0x804a030)+一些魔法来防止异常和多个线程一次调用它。
答案 1 :(得分:4)
没有一个编译器。 gcc可能会这样做,视觉工作室可能会做另一种方式。
从概念上说,有一个隐藏的静态布尔值,编译器正在生成一个if语句。
答案 2 :(得分:0)
函数中的静态在第一次被命中时被调用。例如:
#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");
}
给出这个:
calling foo:
initializing thing
done
foo returned
calling foo:
done
foo returned
答案 3 :(得分:0)
编译器可能会编译以下内容:
void foo1() {
static const char* str = foo2();
}
好像它写成:
void foo1() {
static int __str_initialized = 0;
static const char* str;
if (__str_initialized == 0) {
str = foo2();
__str_initialized = 1;
}
}
请注意,__str_initialized
的初始化可以作为将数据段初始化为0的正常部分发生,因此不需要在那里发生任何特殊情况。
另请注意,这是不线程安全,并且一般来说编译器执行的静态变量初始化将不是线程安全的(也不需要通过标准 - 我不确定什么编译器可以使这个线程安全。)