c++ - Order of evaluation and undefined behaviour -
speaking in context of c++11 standard (which no longer has concept of sequence points, know) want understand how 2 simplest examples defined.
int = 0; = i++; // #0 = ++i; // #1
there 2 topics on explain examples within c++11 context. here said #0
invokes ub , #1
well-defined. here said both examples undefined. ambiguity confuses me much. i've read well-structured reference 3 times topic seems way complicated me.
.
let's analyze example #0
: i = i++;
.
corresponding quotes are:
the value computation of built-in postincrement , postdecrement operators sequenced before side-effect.
the side effect (modification of left argument) of built-in assignment operator , of built-in compound assignment operators sequenced after value computation (but not side effects) of both left , right arguments, , sequenced before value computation of assignment expression (that is, before returning reference modified object)
if side effect on scalar object unsequenced relative side effect on same scalar object, behavior undefined.
as it, side effect of assignment operator not sequenced side effects of it's left , right arguments. side effect of assignment operator not sequenced side effects of i++
. #0
invokes ub.
.
let's analyze example #1
: i = ++i;
.
corresponding quotes are:
the side effect of built-in preincrement , predecrement operators sequenced before value computation (implicit rule due definition compound assignment)
the side effect (modification of left argument) of built-in assignment operator , of built-in compound assignment operators sequenced after value computation (but not side effects) of both left , right arguments, , sequenced before value computation of assignment expression (that is, before returning reference modified object)
if side effect on scalar object unsequenced relative side effect on same scalar object, behavior undefined.
i can not see, how example different #0
. seems ub me same reason #0
. side effect of assignment not sequenced side effect of ++i
. seems ub. topic liked above says well-defined. why?
.
question: how can apply quoted rules determine ub of examples. simple possible explanation appreciated. thank you!
since quotes not directly standard, try give detailed answer quoting relevant parts of standard. definitions of "side effects" , "evaluation" found in paragraph 1.9/12:
accessing object designated volatile glvalue (3.10), modifying object, calling library i/o function, or calling function of operations side effects, changes in state of execution environment. evaluation of expression (or sub-expression) in general includes both value computations (including determining identity of object glvalue evaluation , fetching value assigned object prvalue evaluation) , initiation of side effects.
the next relevant part paragraph 1.9/15:
except noted, evaluations of operands of individual operators , of subexpressions of individual expressions unsequenced. [...] value computations of operands of operator sequenced before value computation of result of operator. if side effect on scalar object unsequenced relative either side effect on same scalar object or value computation using value of same scalar object, behavior undefined.
now let's see, how apply 2 examples.
i = i++;
this postfix form of increment , find definition in paragraph 5.2.6. relevant sentence reads:
the value computation of ++ expression sequenced before modification of operand object.
for assignment expression see paragraph 5.17. relevant part states:
in cases, assignment sequenced after value computation of right , left operands, , before value computation of assignment expression.
using information above, evaluation of whole expression (this order not guaranteed standard!):
- value computation of
i++
(right hand side) - value computation of
i
(left hand side) - modification of
i
(side effect of++
) - modification of
i
(side effect of=
)
all standard guarantees value computations of 2 operands sequenced before value computation of assignment expression. value computation of right hand side "reading value of i
" , not modifying i
, 2 modifications (side effects) not sequenced respect each other , undefined behavior.
what second example?
i = ++i;
the situation quite different here. find definition of prefix increment in paragraph 5.3.2. relevant part is:
if x not of type bool, expression ++x equivalent x+=1.
substituting that, our expression equivalent to
i = (i += 1)
looking compound assignment operator +=
in 5.17/7 i += 1
equivalent i = + 1
except i
evaluated once. hence, expression in question becomes
i = ( = (i + 1))
but know above value computation of =
sequenced after value computation of operands , side effects sequenced before value computations of =
. well-defined order of evaluation:
- compute value of
i + 1
(andi
- left hand side of inner expression)(#1) - initiate side effect of inner
=
, i.e. modify "inner"i
- compute value of
(i = + 1)
, "new" value ofi
- initiate side effect of outer
=
, i.e. modify "outer"i
- compute value of full expression.
(#1): here, i
evaluated once, since i += 1
equivalent i = + 1
except i
evaluated once (5.17/7).
Comments
Post a Comment