11

I can't find a definitive answer for this: does the following code have undefined behavior?

int x = 2;
x+=x+=x+=2.5;
Luc Touraille
  • 79,925
  • 15
  • 92
  • 137
makefun
  • 133
  • 1
  • 6
  • This is *not* a duplicate. Here the expression is `x+=(x+=10)`, which is different from `(x+=10)+=10` - the behavior here is undefined where the other question isn't (in c++11). – interjay Jun 18 '13 at 10:49
  • My above comment refers to the question [In which versions of the C++ standard does “(i+=10)+=10” have undefined behaviour?](http://stackoverflow.com/questions/10655290/in-which-versions-of-the-c-standard-does-i-10-10-have-undefined-behaviou) which was previously marked as duplicate. – interjay Jun 18 '13 at 14:14
  • why do you actually want to know? – Alexander Oh Jun 18 '13 at 15:49
  • 1
    Alex, if this question was to me. I get similar question on interview and I wasn't sure about if it's undefined. Obviously no one would use this sample in real code. – makefun Jun 19 '13 at 08:17

2 Answers2

14

The behavior is undefined. Let's look at the slightly simpler expression:

x += (x+=1)

In C++11, the value computation of the left x is unsequenced relative to the value computation of the expression (x+=1). This means that value computation of x is unsequenced relative to the assignment to x (due to x+=1), and therefore the behavior is undefined.

The reason for this is that the value computation of the two sides of the += operator are unsequenced relative to each other (as the standard doesn't specify otherwise). And 1.9p15 states:

If a side effect on a scalar object is unsequenced relative to either another side effect on the same scalar object or a value computation using the value of the same scalar object, the behavior is undefined.

In C++03 the behavior is undefined because x is modified twice without an intervening sequence point.

Johannes Schaub - litb
  • 496,577
  • 130
  • 894
  • 1,212
interjay
  • 107,303
  • 21
  • 270
  • 254
0

For standard quotes see the other answers. It is likely to find one of two different behaviours in this case.

x += (x += 2);

May either be

x = 2 + 4 (= 6)

if the value of x on left side is evaluated before x+=2 or

x = 4 + 4 (= 8)

if the value of x for the left operator is determined afterwards.


-edit-

I know I not gonna get many fans on SO if I say I don't like those "anything may happen" claims very much. It is true that any compiler can declare itself standard conformant regardless of how the statement we discuss here is handled with respect to the value of x. Nevertheless, I think it doesn't mean that operator += may result in a wrong result or that parantheses may be ignored. Undefined behaviour is not the same as undefined behaviour in any other case.

It is bad to back on any expectation regarding undefined behaviour but in the above example i see good reasons for neglecting any possible outcome but 6 and 8.

In addition I actually suspect x to be 8 after the evaluation of int x=2; x += (x += 2); for most of the established compilers (clang, g++, vc, icpc...).

It is to be said again that you shouldn't rely on such behaviour but that doesn't mean that it is completely unpredictable.

Pixelchemist
  • 24,090
  • 7
  • 47
  • 71
  • 4
    **At least** two behaviors may occur here. The behavior is undefined, so enumerating possible behaviors is an endless task. – Pete Becker Jun 18 '13 at 11:45
  • there is a difference between showing that there exist at least two different outcomes (showing by contradiction) to enumerating. For the case 2 these are identical. – Alexander Oh Jun 18 '13 at 12:57
  • 1
    Optimizing compilers are permitted to *assume* that your program's behavior is not undefined. If you violate that assumption, they can perform transformations that violate *your* assumptions. In any case, it shouldn't really matter how `x += (x += 2);` behaves; whatever it's supposed to mean, there's a clearer way to express it. – Keith Thompson Jun 18 '13 at 15:15