用作自己的初始化程序的未初始化变量的行为是什么? [英] What's the behavior of an uninitialized variable used as its own initializer?

查看:369
本文介绍了用作自己的初始化程序的未初始化变量的行为是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚才注意到,可以使用c99c11c++11标准用clang/gcc/clang ++/g ++编译以下代码.

I noticed just now that the following code can be compiled with clang/gcc/clang++/g++, using c99, c11, c++11 standards.

int main(void) {
    int i = i;
}

,即使使用-Wall -Wextra,也没有编译器报告警告.

and even with -Wall -Wextra, none of the compilers even reports warnings.

通过将代码修改为int i = i + 1;并使用-Wall,他们可能会报告:

By modifying the code to int i = i + 1; and with -Wall, they may report:

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在用于初始化自身时未初始化,因此当时具有不确定值.不确定的值可以是未指定的值陷阱表示.

Because i is uninitialized when use to initialize itself, it has an indeterminate value at that time. An indeterminate value can be either an unspecified value or a trap representation.

如果您的实现支持整数类型的填充位,而 if 所讨论的不确定值恰好是陷阱表示,则使用它会导致不确定的行为.

If your implementation supports padding bits in integer types and if the indeterminate value in question happens to be a trap representation, then using it results in undefined behavior.

如果您的实现没有具有整数填充,则该值只是未指定,并且没有没有未定义的行为.

If your implementation does not have padding in integers, then the value is simply unspecified and there is no undefined behavior.

为进一步详细说明,如果i从未在某个时间获取其地址,则该行为仍可能是不确定的. C11标准的6.3.2.1p2部分对此进行了详细说明:

To elaborate further, the behavior can still be undefined if i never has its address taken at some point. This is detailed in section 6.3.2.1p2 of the C11 standard:

如果左值指定自动存储的对象 寄存器存储可能已经声明的持续时间 类(从未使用过其地址),并且该对象未初始化 (未使用初始化程序进行声明,也没有对其进行赋值 已经在使用前执行过),则该行为是不确定的.

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的地址,则您有未定义的行为.否则,以上声明适用.

So if you never take the address of i, then you have undefined behavior. Otherwise, the statements above apply.

这篇关于用作自己的初始化程序的未初始化变量的行为是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆