刚才注意到下面的代码可以用clang/gcc/clang++/g++编译,使用c99
,c11
,c++11
标准。
int main(void) {
int i = i;
}
即使使用 -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.
我的问题:
- 为什么编译器甚至允许这样做?
- C/C++ 标准对此有何规定?具体来说,这是什么行为? UB 还是依赖于实现?
最佳答案
因为i
在用来初始化自己的时候是未初始化的,所以此时它有一个不确定的值。不确定值可以是未指定值或陷阱表示。
如果您的实现支持整数类型中的填充位,如果所讨论的不确定值恰好是陷阱表示,然后使用它会导致 未定义的行为。
如果您的实现没有在整数中有填充,那么该值只是未指定并且没有未定义的行为。
编辑:
更详细地说,如果 i
从未在某个时刻获取其地址,则该行为仍然是未定义的。这在 C11 标准的第 6.3.2.1p2 节中有详细说明:
If the lvalue designates an object of automatic storage duration that could have been declared with the register storage class (never had its address taken), and that object is uninitialized (not declared with an initializer and no assignment to it has been performed prior to use), the behavior is undefined.
因此,如果您从不获取 i
的地址,那么您的行为未定义。否则,上述陈述适用。
关于c++ - 用作自己的初始化程序的未初始化变量的行为是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54200465/