12

I'm very convinced with the explanation I've found that said that i = ++i is not undefined as far as C++0x is concerned, but I'm unable to judge whether the behavior of i += ++i is well-defined or not. Any takers?

outis
  • 75,655
  • 22
  • 151
  • 221
Saurabh Manchanda
  • 1,115
  • 1
  • 9
  • 21
  • g++ says *yes, it's UB.* – kennytm Oct 14 '10 at 10:44
  • 1
    @KennyTM : I have version 4.5.0 and it warns me of even i = ++i being undefined. What version are you using? Have you succeeded compiling i = ++i without the warning? – Saurabh Manchanda Oct 14 '10 at 10:47
  • both i = ++i and i += ++i are UB – Armen Tsirunyan Oct 14 '10 at 11:16
  • Why is `i = ++i` not undefined in C++0x? Got a link to that explanation? I know they've changed the whole sequence point thing, but haven't read up on the specifics yet. – jalf Oct 14 '10 at 11:43
  • 2
    @Armen : i = ++i is well-defined in C++0x. – Saurabh Manchanda Oct 14 '10 at 11:45
  • @Saurabh: No, it most likely is NOT, although the wording in the standard is a bit unclear. In the discussion I mentioned in my answer most experts said yes, ++++i is well-defined in 0x, but most of them changed their opinion later and came to a conclusion that it is STILL undefined – Armen Tsirunyan Oct 14 '10 at 12:08
  • 3
    @Armen : You might want to read http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#637 – Saurabh Manchanda Oct 14 '10 at 12:29
  • @Saurabh: Ok, you proved your point. Voting to delete my answer. Sorry – Armen Tsirunyan Oct 14 '10 at 12:36
  • Does it matter? Since it is easy to avoid in favour of less ambiguous code, just avoid it. The fact that you have to ask is reason enough not to do it. – Clifford Oct 14 '10 at 14:56
  • @Clifford: I very well know that a code snippet that raises doubts in the readers' mind should never be used but I had started reading the C++0x' draft and this doubt came up. I just had to ask this. – Saurabh Manchanda Oct 14 '10 at 15:13

1 Answers1

9

The reasoning that makes i = ++i well-defined can equally be used to prove that i += ++i must also be well-defined.

i += ++i is equivalent to i += (i += 1) and the new sequencing rules require that the assignment takes place before the value-computation of the i += 1 sub-expression.
This means that the result of the expression i += ++i must be the same as for i = 2 * i + 1.

Edit: I have to revise my answer, because the behaviour is undefined after all.
The behaviour of i += ++i is undefined, because the value-computations of the sub-expressions i (left-hand side argument) and ++i are unsequenced in relation to each other and one of them contains an update of the object i.

This is not a problem for the expression i = ++i, because there the i on the left-hand side does not undergo an lvalue-to-rvalue conversion, which does happen in the i += ++i case.


On a side-note: Don't write such code in any serious project. It relies too much on exactly knowing the sequencing rules and there will be many people who either don't properly understand the sequencing rules, are unaware of the change in the rules that is the result of DR 637 or get tripped up by missing some important aspects of the expression in question (as happened to me when composing the first revision of this answer).

sth
  • 222,467
  • 53
  • 283
  • 367
Bart van Ingen Schenau
  • 15,488
  • 4
  • 32
  • 41
  • i += ++i would be equivalent to i = i + ++i; such that i is evaluated only once. But, is it defined which one of i or ++i is evaluated first? – Saurabh Manchanda Oct 14 '10 at 13:59
  • @Saurabh: You are right. The difference between `i = ++i` and `i += ++i` is the value-computation of the left-hand `i`, which is unsequenced with the `++i`. This makes the result undefined. I will update my answer accordingly. – Bart van Ingen Schenau Oct 14 '10 at 14:44
  • @Bart I wonder what "in all cases, the assignment is sequenced ..." precisely means. What exactly is "the assignment"? A compound-assignment is-an assignment. Can we say that a compound-assignment consists of a prvalue evaluation followed by a side effect? – Johannes Schaub - litb Oct 14 '10 at 20:37
  • I do agree with your interpretation, though. But I wouldn't bet. Also, I would wish the wording would be a little more clear. "The behavior of an expression of the form E1 op = E2 is equivalent to E1 = E1 op E2 except that E1 is evaluated only once. " <- It isn't apparent to me what exactly "is evaluated only once" means. The two "E1" in that second expressions are evaluated differently: First is glvalue evaluation, second is prvalue evaluation. – Johannes Schaub - litb Oct 14 '10 at 20:45
  • @Johannes: The "is evaluated only once" means that the glvalue and the prvalue evaluation have to be done at effectively the same time, or the prvalue evaluation must use the result of the glvalue evaluation. If E1 contains side effects (for example, when it is a function call), then the side effects may only occur once. – Bart van Ingen Schenau Oct 15 '10 at 07:16