问题描述
如果我有:
unsigned int x;
x -= x;
很明显, x
应该在此表达式之后为零,但我所看到的所有地方都说,该代码的行为是不确定的,不仅仅是 x
(直到减法之前)。
it's clear that x
should be zero after this expression, but everywhere I look, they say the behavior of this code is undefined, not merely the value of x
(until before the subtraction).
两个问题:
-
此代码的行为是否确实未定义?
(例如,代码是否在兼容的系统上崩溃[或更糟]?)
Is the behavior of this code indeed undefined?
(E.g. Might the code crash [or worse] on a compliant system?)
如果是的话, 为什么 会明确表示<$>行为是不确定的,因为<$> c $ c> x 在这里应该为零吗?
If so, why does C say that the behavior is undefined, when it is perfectly clear that x
should be zero here?
ie通过在此处未定义行为给出的优点是什么?
i.e. What is the advantage given by not defining the behavior here?
很明显,编译器可以简单地在内部使用被视为方便的任何垃圾值变量,它将按预期工作...该方法出了什么问题?
Clearly, the compiler could simply use whatever garbage value it deemed "handy" inside the variable, and it would work as intended... what's wrong with that approach?
推荐答案
是的,此行为是不确定的,但对于
Yes this behavior is undefined but for different reasons than most people are aware of.
首先,使用单位化的值本身并不是未定义的行为,但是值只是不确定的。如果该值恰好是该类型的陷阱表示,则访问该对象将是UB。无符号类型很少具有陷阱表示形式,因此从那方面来讲,您将相对安全。
First, using an unitialized value is by itself not undefined behavior, but the value is simply indeterminate. Accessing this then is UB if the value happens to be a trap representation for the type. Unsigned types rarely have trap representations, so you would be relatively safe on that side.
使行为未定义的原因是变量的附加属性,即它可以已经用 register
声明过,这是从不使用其地址的。之所以会特别考虑此类变量,是因为有些架构具有真正的CPU寄存器,这些寄存器具有某种未初始化状态且与类型域中的值不对应的额外状态。
What makes the behavior undefined is an additional property of your variable, namely that it "could have been declared with register
" that is its address is never taken. Such variables are treated specially because there are architectures that have real CPU registers that have a sort of extra state that is "uninitialized" and that doesn't correspond to a value in the type domain.
编辑:该标准的相关短语为6.3.2.1p2:
The relevant phrase of the standard is 6.3.2.1p2:
以下代码在所有情况下都是合法的:
And to make it clearer, the following code is legal under all circumstances:
unsigned char a, b;
memcpy(&a, &b, 1);
a -= a;
- 这里
a $的地址c $ c>和
b
被采用,因此它们的值只是不确定的
。 - 由于
unsigned char
从来没有陷阱表示
的不确定值只是未指定,任何unsigned char
的值都可能发生
。 - 最后
a
必须保持值0
。 - Here the addresses of
a
andb
are taken, so their value is justindeterminate. - Since
unsigned char
never has trap representationsthat indeterminate value is just unspecified, any value ofunsigned char
couldhappen. - At the end
a
must hold the value0
.
Edit2: a
和 b
具有未指定的值:
a
and b
have unspecified values:
这篇关于(为什么)使用未初始化变量的未定义行为?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!