8

Possible Duplicate:
Could anyone explain these undefined behaviors (i = i++ + ++i , i = i++, etc…)

In Java the evaluation order is specified to be left-to-right. Is this the case for C and C++ as well, or is it implementation dependent? I do remember that the evaluation order is unspecified for function arguments, but what about sub-expressions?

Community
  • 1
  • 1
Bill the Lizard
  • 398,270
  • 210
  • 566
  • 880
  • Duplicates: http://stackoverflow.com/questions/949433/could-anyone-explain-these-undefined-behaviors-i-i-i-i-i-etc http://stackoverflow.com/questions/1826414/whats-the-value-of-i-i-closed http://stackoverflow.com/questions/1788696/how-the-code-behaves-different-for-java-and-c-compiler – bk1e Mar 03 '10 at 00:30
  • 18
    lol. The mod mod-closed his own question :D – Earlz Mar 03 '10 at 00:33
  • 3
    @bk1e: Thanks for the links. I had a feeling this would be covered here before, but it didn't come up when I asked the question. I figured the quickest way to find the original would be to just ask. :) – Bill the Lizard Mar 03 '10 at 00:34
  • 11
    @Earlz: Once somebody pointed out it's a dupe I pretty much had to. It wouldn't be right for me to leave it open just because it's mine. :) – Bill the Lizard Mar 03 '10 at 00:39
  • @Prasoon: I should hope so ! :) – John Knoeller Mar 03 '10 at 02:46

4 Answers4

14

It is unspecified which of the arguments to + is evaluated first - but that doesn't even matter, because in C and C++, modifying the same object twice without an intervening sequence point is completely undefined behaviour.

Here you're modifying x three times without an intervening sequence point, so you're well into here be dragonnes territory ;)


The relevant part of the C99 standard is "6.5 Expressions":

2 Between the previous and next sequence point an object shall have its stored value modified at most once by the evaluation of an expression. Furthermore, the prior value shall be read only to determine the value to be stored.

and

3 The grouping of operators and operands is indicated by the syntax. Except as specified later (for the function-call (), &&, ||, ?:, and comma operators), the order of evaluation of subexpressions and the order in which side effects take place are both unspecified.


It's possible to write legal code that demonstrates the unspecified order of evaluation - for example:

#include <stdio.h>

int foo(void)
{
    puts("foo");
    return 1;
}

int bar(void)
{
    puts("bar");
    return 2;
}

int main()
{
    int x;

    x = foo() + bar();
    putchar('\n');

    return x;
}

(It is unspecified whether you get output of foobar or barfoo).

caf
  • 233,326
  • 40
  • 323
  • 462
4

C++03 Standard 5.4

Except where noted, the order of evaluation of operands of individual operators and subexpressions of individual expressions, and the order in which side effects take place, is unspecified.53) Between the previous and next sequence point a scalar object shall have its stored value modified at most once by the evaluation of an expression. Furthermore, the prior value shall be accessed only to determine the value to be stored. The requirements of this paragraph shall be met for each allowable ordering of the subexpressions of a full expression; otherwise the behavior is undefined.

... hence, undefined and implementation dependant.

Kornel Kisielewicz
  • 55,802
  • 15
  • 111
  • 149
3

The C standard does not guarantee that the post-increment will actually "happen" after the pre-increment. So that is undefined behaviour.

Earlz
  • 62,085
  • 98
  • 303
  • 499
2

That's not a valid C statement, so it doesn't make sense to talk about the evaluation order.

Stephen Canon
  • 103,815
  • 19
  • 183
  • 269
  • 1
    What do you mean by "valid"? It successfully compiles in gcc and g++. – nobody Mar 03 '10 at 00:32
  • 4
    Whether or not a file is successfully compiled by gcc has nothing to do with whether or not it contains valid C statements. The C standard determines what is valid C, not one compiler. – Stephen Canon Mar 03 '10 at 00:39
  • 4
    This statement is syntactically valid, although semantically incorrect as it causes undefined behaviour. – qrdl Mar 03 '10 at 07:52