想象一下:
int X;
X = X;
这将是未定义的行为
1 在以下情况下行为未定义:
[...]
具有自动存储持续时间的对象的值在不确定时使用(6.2.4、6.7.8、6.8)。
但是这个呢?
int X;
X;
X;
引用引用的调用是否允许编译器导致未定义的行为?或者这不算作 X 被“使用”?
想象一下:
int X;
X = X;
这将是未定义的行为
1 在以下情况下行为未定义:
[...]
具有自动存储持续时间的对象的值在不确定时使用(6.2.4、6.7.8、6.8)。
但是这个呢?
int X;
X;
X;
引用引用的调用是否允许编译器导致未定义的行为?或者这不算作 X 被“使用”?
在 C 1999 中,使用未初始化的对象并不是直接错误。(您对附件 J 的引用不是标准的规范部分;它们只是提供信息。)具有自动存储持续时间的未初始化对象具有不确定的值。对于某些对象,该值可能是陷阱表示,因此使用它可能会导致未定义的行为。
但是,对于某些对象,可以确定未初始化的对象不能具有陷阱值。例如,anunsigned char
不能有陷阱值,并且 中定义的精确宽度有符号整数类型stdint.h
不能有陷阱值(因为它们是没有填充位的二进制补码)。对于其他类型,可能是您的 C 实现定义的属性导致它们没有陷阱值。在所有 C 1999 实现中使用未初始化的int X
行为并没有定义(但在某些实现中),但使用未初始化的unsigned char X
行为确实如此。
在 C 2011 中,此文本在 6.3.2 2 中添加:“如果左值指定了一个可以使用寄存器存储类声明的具有自动存储持续时间的对象(从未被占用其地址),并且该对象未初始化(未用初始化器声明并且在使用之前没有对其进行赋值),行为是未定义的。” 因此,在 C 2011 中,两者都X = X;
具有X;
未定义的行为。
历史/背景:
C 2011 更改支持惠普机器,该机器具有用于某些寄存器的特殊标志,指示寄存器内容是否有效。如果在内容无效的情况下使用了寄存器,机器会产生异常。因此,如果编译器将X
of分配unsigned char X
给这样的寄存器,即使没有unsigned char
陷阱值,在无效时使用该寄存器也可能导致机器异常。
X = X;
以上是未定义的行为。因为X
没有初始化。编译器至少应该对此产生警告。
标准规定 6.3.2.1p2:
如果左值指定了一个可以使用寄存器存储类声明的具有自动存储持续时间的对象(从未使用过它的地址),并且该对象未初始化(未使用初始化程序声明并且在使用之前未对其进行分配),行为未定义。
然而:
X;
上面类似:
1212342413;
正如X
将评估为某些表达式。