c++ - 用作自己的初始化程序的未初始化变量的行为是什么?

标签 c++ c initialization language-lawyer

刚才注意到下面的代码可以用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/

相关文章:

c++ - T() 应该将成员变量初始化为零吗?

c - 将数组字符串传递给函数指针?

c - 在 C 中初始化嵌套结构的正确方法

c# - 无法使用/调试来自 C# 的非托管 DLL

c++ - 这个 'missing template arguments' C++ 错误是什么意思

被跳过的字符是输出文件 i/o

c - 在没有表模式的情况下将 CSV 导入 SQLite

java - 初始化包含对象数组的 Java 对象实例

c++ - 将全局变量定义为散列

c++ - 不执行参数化基类构造函数就存在中间类