Take the 2-minute tour ×

I have started studying about C++0x. I came across the follow expression somewhere:

int l = 1, m=2;
++l *= m;

I have no idea whether the second expression has well defined behavior or not. So I am asking it here.

Isn't it UB? I am just eager to know.

share|improve this question
The question is in context of c++0x. –  Lawrence Dec 2 '10 at 16:08
You are correct, I take my comments back, and I hereby declare my previous ignorance of the sequence order. –  Suma Dec 2 '10 at 16:25
The result of ++l is a non const reference? Why did the C++ language designers define it like that? –  CodesInChaos Dec 2 '10 at 16:51
Seriously, why do people write code like this in the first place??? –  FredOverflow Dec 2 '10 at 18:00
I second Freds statement, if you have to ask, don't do it. –  Harald Scheirich Dec 2 '10 at 19:20
show 3 more comments

2 Answers

up vote 3 down vote accepted

In the code above, prefix ++ has precedence over *=, and so gets executed first. The result is that l equals 4.

UPDATE: It is indeed undefined behavior. My assumption that precedence ruled was false.

The reason is that l is both an lvalue and rvalue in *=, and also in ++. These two operations are not sequenced. Hence l is written (and read) twice "without a sequence point" (old standard wording), and behavior is undefined.

As a sidenote, I presume your question stems from changes regarding sequence points in C++0x. C++0x has changed wording regarding "sequence points" to "sequenced before", to make the standard clearer. To my knowledge, this does not change the behavior of C++.

UPDATE 2: It turns out there actually is a well defined sequencing as per sections 5.17(1), 5.17(7) and 5.3.2(1) of the N3126 draft for C++0x. @Johannes Schaub's answer is correct, and documents the sequencing of the statement. Credit should of course go to his answer.

share|improve this answer
No, to my understanding this is correct. See my comment on your answer. –  Håvard S Dec 2 '10 at 22:58
It's not undefined behaviour... but explaining why wouldn't fit in this space. Apparently the validity of such a statement wasn't intentional and is just a side-effect of fixing another issue with the language... none the less the gurus decided it was good for C++ so it's going to remain valid. IMO the net effect is that people will read here that this is valid and will write that kind of code and apparently innocent variations of it (that are however UB) in C++ programs. How tricky can be ? For example i = i++ + 1 is UB, while i = ++i + 1 is valid. I'm NOT kidding. –  6502 Dec 2 '10 at 22:59
@6502 Could you please enlighten us with a citation? –  Håvard S Dec 2 '10 at 23:02
The question involves ++L that is equivalent to (L+=1) (see 5.3.2(1)). L+=1 is a compound assignment (see 5.17(1)). The relevant part is "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.". Now the value of the assignment is needed by *= (that is another compound assignment) and is sequenced before the assignment. No multiple unsequenced side effects to L are present so the code is valid. Yes I agree this sucks. –  6502 Dec 2 '10 at 23:34
show 5 more comments

The expression is well defined in C++0x. A very Standardese quoting FAQ is given by Prasoon here.

I'm not convinced that such a high ratio of (literal Standards quotes : explanatory text) is preferable, so I'm giving an additional small explanation: Remember that ++L is equivalent to L += 1, and that the value computation of that expression is sequenced after the increment of L. And in a *= b, value computation of expression a is sequenced before assignment of the multiplication result into a.

What side effects do you have?

  • Increment
  • Assignment of the multiplication result

Both side-effects are transitively sequenced by the above two sequenced after and sequenced before.

share|improve this answer
No. IIUC the standard the side effect of (L += 1) is initiated after the value computation but you cannot assume that it will complete before the other side effect (of *=) is initiated. The code generated be the compiler could wait until the very end of the full-expression before actually complete the update of L. –  6502 Dec 2 '10 at 20:48
@6502 I have read all this out of the draft Standard weeks ago and this has been debated at length on SO elsewhere. My explanation and @Prasoon's Standard quotes should get you started to take n3126 and read in it and verifying the validness of it. The side effect of L += 1 is initiated by evaluating that expression, and is sequenced after value computation of L and before value computatin of that entire expression. Sequenced-before/after is transitive, so if A is sequenced-before B and B is sequenced-before C, then A is sequenced before C. –  Johannes Schaub - litb Dec 2 '10 at 21:01
I'm not going to discuss this another time here, by all means. –  Johannes Schaub - litb Dec 2 '10 at 21:01
@Johannes: Ok. I voted for deleting my wrong reply. It has been long I didn't dig into internals of C++ and in retrospect I think it was a good idea. IMO the last thing on earth that C++ needed was increasing complexity and asymmetries... but apparently this is exactly what happened. The pointed discussion says that it was good to remove some UB... but I don't agree; this is obtained by special casing and increasing complexity for UB classification so MORE programmers will make mistakes in those areas. i = ++i + 1 will work, but by mere coincidence and not by deliberate programmmer's choice. –  6502 Dec 2 '10 at 22:42
See my discussion with @6502 in my initial answer. I was unable to grasp that the lvalue computations of l were actually sequenced as per 5.17(1). Correlating with and 5.17(7) enlightened me. Thanks for having patience. :) –  Håvard S Dec 3 '10 at 0:09
show 10 more comments

Your Answer


