C与C++中具有静态存储持续时间的对象的初始化

foo*_*ool 11 c c++ initialization definition

可能重复:
主要回报是什么?

例如,以下代码编译时没有任何警告:

#include <stdio.h>

int i = i + 1;

int main(int argc, char *argv[])
{

    fprintf (stderr, "%d\n", i);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我认为这在语法上是非法的,因为i它在声明之前使用,是不是?

在我看来,外观int i = i + 1;肯定是一个错误,为什么编译器没有警告呢?我使用gcc 4.5.1.

Mat*_*lia 7

(注意:我指的是当前的C++标准)

我不是很确定这一点,但是,如果我对标准的解释是正确的,那么代码应该没问题而不是UB.

该变量的第一初始化为零初始化具有静态存储持续时间的对象发生这种情况的任何其它初始化发生之前(§3.6.21).

所以,首先i设置为零.

然后,进行动态初始化(即非零和非常量初始化),因此它使用当前值i(0)来再次实际初始化它.最后它应评估为1.

这似乎由§8.56证实,它明确地说:

在任何其他初始化发生之前,任何静态存储持续时间对象占用的内存应在程序启动时进行零初始化.[注意:在某些情况下,稍后会进行额外的初始化.]

(如果你在分析中发现一些缺陷,请在评论中告诉我,我会很乐意纠正/删除答案,这是很滑的地板,我很清楚:))


Pra*_*rav 5

在C++中,它在语法上是正确的.在C中,您只能使用常量初始化全局变量.所以你的代码不能用C编译.

在C中这是合法的BTW

int main()
{
   int i = i+1;
}
Run Code Online (Sandbox Code Playgroud)

3.3.1/1声明点

名称的声明点紧跟在其完整的声明符之后和初始化器之前(如果有的话).

行为已明确定义为§3.6.2/1:

"在进行任何其他初始化之前,具有静态存储持续时间(3.7.1)的对象应进行零初始化(8.5)."