请考虑以下代码示例:
#include <iostream>
static int bar = bar;
int main()
{
int foo = foo;
std::cout << "foo = " << foo << std::endl;
std::cout << "bar = " << bar << std::endl;
}
我收到以下编译器警告:
main.cpp: In function 'int main()':
main.cpp:7:15: warning: 'foo' is used uninitialized in this function [-Wuninitialized]
int foo = foo;
^
输出:
foo = 0
bar = 0
我期待这个警告,因为foo被用于整体化。而不是0,'foo'可以是任何东西。 自我赋值未定义。
但为什么“酒吧”的自我指派没有被警告?这个“bar”的赋值是定义的还是未定义的行为?为什么?
我知道,elementar数据类型的静态变量用'0'初始化,但在这种情况下,变量'bar'在初始化期间使用。我想知道,如果这是定义的行为,'0'是预期的输出。 (这可以解释,没有发生编译器警告)。
答案 0 :(得分:14)
我认为标准的一部分与您的问题相关(§3.6.2/ 2):
具有静态存储持续时间(3.7.1)或线程存储持续时间(3.7.2)的变量应为零初始化(8.5) 在进行任何其他初始化之前。[...]
所以在这种情况下,即使在编译器查看bar
的定义之前,它已经对它进行了零初始化。
正如标准中进一步指出的那样,静态变量初始化应该有两个阶段(强调我的)。
一起,零初始化和常量初始化称为静态初始化;所有其他初始化 是动态初始化。 静态初始化应在任何动态初始化之前执行。