0

I have a friend who is getting different output than I do for the following program:

int main() {
    int x = 20, y = 35;
    x = y++ + x++;
    y = ++y + ++x;

    printf("%d%d", x, y);

    return 0;
}

I am using Ubuntu, and have tried using gcc and clang. I get 5693 from both.

My friend is using Visual Studio 2015, and gets 5794.

The answer I get (5693) makes most sense to me, since:

  1. the first line sets x = x + y (which is x = 20+35 = 55) (note: x was incremented, but assigned over top of, so doesn't matter)
  2. y was incremented and is therefore 36
  3. next line increments both, adds the result and sets it as y (which is y = 37 + 56 = 93)
  4. which would be 56 and 93, so the output is 5693

I could see the VS answer making sense if the post-increment happened after the assignment. Is there some spec that makes one of these answers more right than the other? Is it just ambiguous? Should we fire anyone who writes code like this, making the ambiguity irrelevant?

Note: Initially, we only tried with gcc, however clang gives this warning:

coatedmoose@ubuntu:~/playground$ clang++ strange.cpp 
strange.cpp:8:16: warning: multiple unsequenced modifications to 'x' [-Wunsequenced]
    x = y++ + x++;
      ~        ^
1 warning generated.
CoatedMoose
  • 3,624
  • 1
  • 20
  • 36
  • GCC [gives me warnings](http://coliru.stacked-crooked.com/a/c7c7667511ece841). Make sure you're using a reasonably recent version and have warnings enabled. – chris Jun 23 '16 at 00:03

1 Answers1

1

The Clang warning is alluding to a clause in the standard, C++11 and later, that makes it undefined behaviour to execute two unsequenced modifications to the same scalar object. (In earlier versions of the standard the rule was different although similar in spirit.)

So the answer is that the spec makes all possible answers equally valid, including the program crashing; it is indeed inherently ambiguous.

By the way, Visual C++ actually does have somewhat consistent and logical behaviour in such cases, even though the standard does not require it: it performs all pre-increments first, then does arithmetic operations and assignments, and then finally performs all post-increments before moving on to the next statement. If you trace through the code you've given, you'll see that Visual C++'s answer is what you would expect from this procedure.

Brian Bi
  • 111,498
  • 10
  • 176
  • 312
  • What I expect is what gcc and clang did. Treating `++` as a f'n takes a reference and returns that value (via an intermediate temp var) then incements the value at the reference makes sense to me. I concede that what Visual C++ is consistent, and I can understand how to interpret it, but I don't like it. – CoatedMoose Jun 23 '16 at 00:47