1

Here is a question I can not explain clearly.


Which option is wrong and why?

(A) a += (a++);   
(B) a += (++a);
(C) (a++) += a;
(D) (++a) += (a++);

What is the difference between A and B?

My understand: A is a UB but B is OK because the side effect of ++a will be completed before the assignment. Is that right?

Update: What is the difference between ++a and a++ within the sequence point? The side effect of pre-increment(decrement) may be completed any time before the next seq-point just like post-increment(decrement)?

Donglei
  • 275
  • 1
  • 10

2 Answers2

6

Which option is wrong and why?

All of them are wrong, and that's because the first two invoke undefined behavior, and the last two don't compile. (And if they did, they would invoke UB as well.)

  • Why the second one is UB? `a+=(++a)` is equal to `++a; a+=a;` – Donglei Aug 22 '13 at 14:15
  • 4
    @Donglei Oh huh? [Assignment is not a sequence point.](http://stackoverflow.com/questions/4362501/any-good-reason-why-assignment-operator-isnt-a-sequence-point) –  Aug 22 '13 at 14:17
  • Yes, I know assignment is not a sequence point. Can you explain what is the difference between `++a` and `a++` within the sequence point? My understand: Pre-increment will `++` before return so after `++a` the side-effect has already happend. – Donglei Aug 22 '13 at 14:35
  • 2
    @Donglei And it doesn't matter when the side effects take place, since either way, **`a` is modified twice between sequence points.** –  Aug 22 '13 at 14:36
  • Yes, exactly. But what about the difference between `++a` and `a++` within the sequence point? I think this is what I confused actually. – Donglei Aug 22 '13 at 14:44
  • @Donglei Nothing, since the code invokes UB, so there's no point in reasoning about what it does. If you write code that has defined behavior, though, then what you already explained applies (i. e. `a++` yields `a` and `++a` yields `a + 1`). –  Aug 22 '13 at 14:47
  • @Donglei: pre-increment doesn't work the way you think it does; the expression `++a` will evaluate to the current value of `a` + 1, but the *side effect* of updating `a` doesn't have to happen immediately; in that respect it behaves exactly like the postfix version. – John Bode Aug 22 '13 at 16:54
2

The first and second is UB because C does not define what is supposed to be evaluated first.

The third and fourth do not compile - the reason: lvalue required as left operand of assignment

Let me be more specific on the first two:

a += (a++); - equal to a = a + (a++);

  • if the a++ is evaluated first then it's a = a + 1 + a;
  • if the a++ is evaluated at the end then it's a = a + a;

but C does not define what should happen first, so it depends on the implementation, and it's UB.

The same goes for the second.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
No Idea For Name
  • 11,411
  • 10
  • 42
  • 70