Hon*_*hen 15 c c++ initialization language-lawyer
我刚才下面的代码可以用铿锵/ GCC /铛++/G ++编译注意到,使用c99
,c11
,c++11
标准.
int main(void) {
int i = i;
}
Run Code Online (Sandbox Code Playgroud)
甚至-Wall -Wextra
,没有一个编制者甚至报告警告.
通过修改代码int i = i + 1;
和使用-Wall
,他们可能会报告:
why.c:2:13: warning: variable 'i' is uninitialized when used within its own initialization [-Wuninitialized]
int i = i + 1;
~ ^
1 warning generated.
Run Code Online (Sandbox Code Playgroud)
我的问题:
Jea*_*bre 11
这是一个警告,它与标准无关.
警告是启发式的"乐观"方法.仅当编译器确定它将成为问题时才会发出警告.在这种情况下,你有更好的运气clang
或gcc
评论中所述的最新版本(参见我的另一个相关问题:为什么我在这个简单的例子中没有得到gcc的"未使用的未初始化"警告?).
无论如何,在第一种情况下:
int i = i;
Run Code Online (Sandbox Code Playgroud)
从来没有做过什么i==i
.由于它没用,因此可能会完全优化分配.对于没有"看到"自我初始化作为问题的编译器,您可以在没有警告的情况下执行此操作:
int i = i;
printf("%d\n",i);
Run Code Online (Sandbox Code Playgroud)
虽然这会触发警告:
int i;
printf("%d\n",i);
Run Code Online (Sandbox Code Playgroud)
尽管如此,不要对此进行警告已经足够糟糕了,因为从现在开始i
被视为初始化.
在第二种情况:
int i = i + 1;
Run Code Online (Sandbox Code Playgroud)
1
必须执行未初始化值之间的计算.那里发生了未定义的行为.
dbu*_*ush 11
因为i
在初始化自身时未初始化,因此当时它具有不确定的值.不确定的值可以是未指定的值或陷阱表示.
如果您的实现支持整数类型的填充位,并且如果所讨论的不确定值恰好是陷阱表示,那么使用它会导致未定义的行为.
如果您实现不没有在整数填充,那么值就是不确定并没有任何不确定的行为.
编辑:
进一步详细说明,如果i
从未在某个时刻采取过地址,那么行为仍然可以是未定义的.这在C11标准的6.3.2.1p2节中详细说明:
如果左值指定了一个自动存储持续时间的对象,该对象可以使用寄存器存储类声明(从未使用其地址),并且该对象未初始化(未使用初始化程序声明,并且在使用之前未对其进行任何赋值) ),行为未定义.
因此,如果您从未获取地址i
,那么您有未定义的行为.否则,上述声明适用.
归档时间: |
|
查看次数: |
1315 次 |
最近记录: |