问题
In another answer it was stated that prior to C++11, where i
is an int
, then use of the expression:
*&++i
caused undefined behaviour. Is this true?
On the other answer there was a little discussion in comments but it seems unconvincing.
回答1:
It makes little sense to ask whether *&++i
in itself has UB. The deferencing doesn't necessarily access the stored value (prior or new) of i
, as you can see by using this as an initializer expression for a reference. Only if an rvalue conversion is involved (usage in such context) is there any question to discuss at all. And then, since we can use the value of ++i
, we can use the value of *&++i
with exactly the same caveats as for ++i
.
The original question concerned essentially i = ++i
, which is the same as i = *&++i
. That was undefined behavior in C++03, due to i
being modified twice between sequence points, and is well-defined in C++11, due to the side-effects of the assignment operator being sequenced after the value computations of the left and right hand sides.
It is perhaps relevant to note that the non-normative examples in the C++98 and C++03 standards, were incorrect, describing some cases of formally Undefined Behavior as merely unspecified behavior. Thus, the intent has not been entirely clear, all the way back. A good rule of thumb is to simply not rely on such obscure corner cases of the language, to avoid them: one should not need to be a language lawyer in order to make sense of the code…
回答2:
I think the question only makes sense if we deal with the expression:
i = *&++i;
The relevant quote in the C++03 standard would be [expr]/4:
Except where noted, the order of evaluation of operands of individual operators and subexpressions of individual expressions, and the order in which side effects take place, is unspecified. Between the previous and next sequence point a scalar object shall have its stored value modified at most once by the evaluation of an expression. Furthermore, the prior value shall be accessed only to determine the value to be stored. The requirements of this paragraph shall be met for each allowable ordering of the subexpressions of a full expression; otherwise the behavior is undefined.
i = ++i + 1; // the behavior is unspecified
We can just compare the sequencing of i = *&++i
vs i = ++i + 1
to determine that the same rule causes both to be unspecified. They are both statements of the form:
i = f(++i);
For any function f
, the reading of i
on the left-hand side and the side-effect of the ++i
on the right-hand side are not sequenced relative with each other. Hence, undefined behavior.
来源:https://stackoverflow.com/questions/28465121/does-i-cause-undefined-behaviour-in-c03