5

Consider the following expression (with declaration for exposition):

int n = 42;
--n &= 0x01;

Does this fall foul of sequencing rules?

In my opinion, the pre-increment is needed as part of the "value computation" of the left-hand operand. If this is true, there's no UB here since C++11 (and, since C++17, both value computations and side effects are sequenced relative to the assignment).

If it were a post-increment, then the modification of n would be merely a side-effect and we'd not have good sequencing (until C++17).

TonySalimi
  • 8,257
  • 4
  • 33
  • 62
Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055

2 Answers2

3

I suppose you are right, here's what standard says:

8.5.18 Assignment and compound assignment operators

All require a modifiable lvalue as their left operand; their result is an lvalue referring to the left operand. [...] In all cases, the assignment is sequenced after the value computation of the right and left operands, and before the value computation of the assignment expression.

So from above it seems assignment is value expression and both left and right of assignment are evaluated before assignment.

From standard about the preincrement:

8.5.2.2 Increment and decrement

The result is the updated operand; it is an lvalue, and it is a bit-field if the operand is a bit-field. The expression ++x is equivalent to x+=1.

Which means that even before C++17 its side effect is sequenced before value computation.

Community
  • 1
  • 1
bartop
  • 9,971
  • 1
  • 23
  • 54
0

As far as I can tell the wording in C++11 doesn't mention the "value computation" of preincrement and predecrement in relation to the update:

[expr.pre.incr]

1 The operand of prefix ++ is modified by adding 1, or set to true if it is bool (this use is deprecated). The operand shall be a modifiable lvalue. The type of the operand shall be an arithmetic type or a pointer to a completely-defined object type. The result is the updated operand; it is an lvalue, and it is a bit-field if the operand is a bit-field. If x is not of type bool, the expression ++x is equivalent to x+=1.

There is nothing in the above paragraph from which I'd conclude the modification has to come first. An implementation may very well compute the updated value (and use it) prior to writing it into the object by the next sequence point.

In which case we will have ourselves a side-effect that is indeterminately sequenced with another modification. So I'd say since the standard doesn't specify if there is a side-effect, nor how such potential side-effect is to be sequenced, the whole thing is undefined by omission.

With C++17, we of course get well defined sequencing with or without this potential side-effect.

StoryTeller - Unslander Monica
  • 165,132
  • 21
  • 377
  • 458