c - 如果 a 未初始化,a^a 或 a-a 是未定义的行为吗?

标签 c undefined-behavior

考虑这个程序:

#include <stdio.h>

int main(void)
{
    unsigned int a;
    printf("%u %u\n", a^a, a-a);
    return 0;
}

这是未定义的行为吗?

从表面上看,a 是一个未初始化的变量。所以这指向未定义的行为。但是对于a的所有值,a^aa-a都等于0,至少我认为是案子。是否有可能通过某种方式证明该行为已明确定义?

最佳答案

在 C11 中:

  • 根据 6.3.2.1/2,如果 a 的地址从未被占用(引用如下),则它是明确未定义的
  • 它可能是一个陷阱表示(在访问时会导致 UB)。 6.2.6.1/5:

Certain object representations need not represent a value of the object type.

无符号整数可以有陷阱表示(例如,如果它有 15 个精度位和 1 个奇偶校验位,访问 a 可能会导致奇偶校验错误)。

6.2.4/6 说初始值是不确定的,3.19.2 下的定义是未指定值或陷阱表示。 p>

进一步:在 C11 6.3.2.1/2 中,正如 Pascal Cuoq 所指出的:

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.

这对字符类型没有异常(exception),所以这个条款似乎取代了前面的讨论;即使不存在陷阱表示,访问 x 也是立即未定义的。本条款was added to C11以支持实际上具有寄存器陷阱状态的安腾 CPU。


没有陷阱表示的系统:但是如果我们放入 &x; 以便 6.3.2.1/2 的反对意见不再适用,并且我们在一个系统上已知没有陷阱表示?然后该值是一个未指定的值。 3.19.3 中unspecified value 的定义有点模糊,不过 DR 451 已经澄清了,结论是:

  • 在所述条件下未初始化的值可能会改变其值。
  • 对不确定值执行的任何操作都会产生不确定值。
  • 库函数在用于不确定值时会表现出未定义的行为。
  • 这些答案适用于所有没有陷阱表示的类型。

在这个决议下,int a; &一种; int b = a - a; 导致 b 仍然具有不确定的值。

请注意,如果未将不确定值传递给库函数,我们仍处于未指定行为(而非未定义行为)的范围内。结果可能很奇怪,例如if ( j != j ) foo(); 可以调用 foo,但恶魔必须留在鼻腔中。

关于c - 如果 a 未初始化,a^a 或 a-a 是未定义的行为吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25074180/

相关文章:

c - 函数 shmdt() 有什么问题?

c - 读取文件 - 逐行创建排列在c中

c - OpenGL矩形动画

c - 需要使用 OpenSSL 3.0.8 库解密的帮助

c - 为什么我收到 "Segmentation fault: 11"

c++ - 为什么不能用 memcpy 复制非 POD 对象?

c++ - 我可以获取数组的最后一个元素的地址吗?

c - 可变参数宏 : Different output for identical code

c - C的未指定,未定义和实现定义的行为WIKI

c++ - 是否修改 const 对象的内部字节未定义行为,以防它包含由放置 new 构造的另一个对象?