问题
This is a follow-on from a discussion, which I think deserves a question of its own.
Basically, is the result of this undefined?
int x;
int y = 1 || x;
There are two "common-sense" arguments here:
- Mathematically speaking, no matter what the value of
x
, the value ofy
should be1
. - Because of short-circuiting,
x
is never evaluated anyway.
But the counterargument is that we have an expression that involves an uninitialized variable, so all bets are off (in theory).
More generally, if the value of an uninitialized variable can't possibly affect the result of an expression, is it "safe"? e.g.:
int x;
int y = x - x;
Usual disclaimer: Of course, I'm not advocating ever writing code like this.
回答1:
In C, it is undefined behavior to use the value of an object with automatic storage duration while it is indeterminate. (J.2, informative) but it's OK for variables with automatic storage duration to hold an indeterminate value.
An expression can only have its value used if it is evaluated and according to 6.5.12 (Logical OR operator) the second operand is not evaluated (let alone have its value used) if the first operand compares unequal to 0.
回答2:
Disclaimer: I thought the question was for C++ as well. Apparently it is for C only. I don't speak C-standardese, but I believe my answer holds true for C as well, although using different termiology
int x;
int y = 1 || x;
is well defined because x is simply not evaluated - guarantee of short-circuit evaluation of ||.
int x;
int y = x - x;
invokes undefined behvior, because x is evaluated and an lvalue-to-rvalue conversion takes place. If that conversion didn't take place, the behavior would be well-defined, for example:
int x;
int* y = &x;
int z = &x - &x;
Here x is also evaluated but no lvalue-to-rvalue conversion takes place, so it's defined.
回答3:
Regarding y = x - x;
, one worst-case scenario to bear in mind is that an uninitialized variable might contain a trap value.
You can't rely on the presence of an optimizer to realise that x - x
doesn't actually depend on the value of x
, and so certainly the implementation is allowed to use the value of x
in evaluating x - x
, and it's used in the abstract machine.
So if it's a trap value, you'd have a hardware error or whatever the implementation does when it traps. UB, anyway.
I remember that one system I used added extra guarantees about the behavior of indeterminate values. It stated that using an indeterminate value would not explode, but also was not required to behave as if the value was any actual value of the type. So, x-x
would result in another indeterminate value, not necessarily 0. This is actually less useful than trapping, since it stores up the programming error for later use when you least expect it, but AFAIK it's completely conforming since behaviour is not defined by the standard.
回答4:
Basically, is the result of this undefined?
int x; int y = 1 || x;
Nopes! x
is never used/ evaluated.
int y = x - x;
invokes UB.
来源:https://stackoverflow.com/questions/7269545/if-the-value-of-an-uninitialized-variable-shouldnt-affect-the-value-of-an-expre