当前位置: 首页 > 知识库问答 >
问题:

(为什么)使用未初始化的变量是未定义的行为?

归翔
2023-03-14

如果我有:

unsigned int x;
x -= x;

很明显,这个表达式后面的x应该是零,但我看到的任何地方,他们都说这个代码的行为是未定义的,而不仅仅是x的值(直到减法之前)。

很明显,编译器可以简单地在变量中使用它认为“方便”的任何垃圾值,并且它将按照预期工作。这种方法有什么问题?

共有1个答案

岳正阳
2023-03-14

是的,这种行为是没有定义的,但原因不同于大多数人意识到的。

首先,使用统一化的值本身并不是未定义的行为,但该值只是不确定的。如果该值恰好是该类型的陷阱表示,那么访问该值就是UB。无符号类型很少具有陷阱表示,因此在这方面相对安全。

使行为未定义的是变量的一个附加属性,即它“可以用register声明”,即它的地址从未被采用。这类变量被特别处理,因为有些体系结构具有真正的CPU寄存器,这些寄存器具有某种“未初始化”的额外状态,并且与类型域中的值不对应。

如果lvalue指定了一个具有自动存储持续时间的对象,该对象本可以使用register storage类声明(从未使用过其地址),并且该对象未初始化(未使用初始化器声明,并且在使用之前未对其执行赋值),则该行为未定义。

更明确的是,以下守则在任何情况下都是合法的:

unsigned char a, b;
memcpy(&a, &b, 1);
a -= a;
  • 这里取AB的地址,因此它们的值不确定。
  • 由于unsigned char从不具有未指定值的陷阱表示,因此unsigned char的任何值都可能发生。
  • 结尾A必须包含值0

3.19.3未指定值
本国际标准在任何情况下均不要求选择值的相关类型的有效值

 类似资料: