Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is "++l *= m" undefined behaviour?

Tags:

c++

c++11

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.

like image 358
Lawrence Avatar asked Dec 02 '10 15:12

Lawrence


2 Answers

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.

like image 158
Johannes Schaub - litb Avatar answered Sep 22 '22 21:09

Johannes Schaub - litb


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.

like image 38
Håvard S Avatar answered Sep 26 '22 21:09

Håvard S