views:

699

answers:

7

x = 1 i expect the answer to be 11, but it comes out to be 12.

+52  A: 

We explain it by expecting undefined behaviour rather than any particular result. As the expression attempts to modify x multiple times without an intervening sequence point its behaviour is undefined.

Charles Bailey
Welcome to C/C++ world.
bua
+1 I just tried this using gcc 3.2.2 on Linux, and the expression returns 10 (9 and 12 eat your heart out...)
Todd Owen
see also: http://stackoverflow.com/questions/98242/why-is-foon-n-not-working
Dustin Getz
Here is an imho nice sequence point description in the GCC manual: http://gcc.gnu.org/onlinedocs/gcc-4.4.1/gcc/Warning-Options.html#index-Wsequence_002dpoint-278
Johannes Schaub - litb
Then why isn't it a syntax error? Anything ambiguous that makes it into compiled code...seems like an oversight.
Alex Feinman
@Alex Feinman: forcing conforming implementations to diagnose an error adds an extra burden to implementers. Whether this cost outweighs the benefit for users is a judgement call. Often the C++ standard comes down on the side of not burdening implementers unnecessarily. Given the complexity of writing a C++ implementation this may be no bad thing.
Charles Bailey
@Alex Feinman: That's like asking why this isn't a syntax error: "MyClass ptr->doSomething();" Because no one who knows better will write that.
Bill
@Bill: it's not really like asking that, since your example requires DFA to analyse, whereas "multiple sub-expressions of an expression which modify the same variable and are not separated in the full expression by a sequence point" is at least theoretically diagnosable just by local analysis of the expression. But the way the C++ standard expresses the rule is "any allowable execution order of the expression" has no sequence-point separator, and implementations are quite reasonably not expected to reason about all legal execution orders.
Steve Jessop
...and in any case even though this example with repeated use of `x` is not actually that hard to diagnose, if there could be aliases involved in the expression then it would be. Often half a job of catching errors is worse than none at all, since it encourages people to mistakenly think they don't have to think about that class of error because the compiler will do it for them.
Steve Jessop
@Bill, that's something that your IDE should catch. Mine does...
Alex Feinman
+3  A: 

This is actually undefined. C++ doesn't define explicitly the order of execution of a statement so it depends on the compiler and this syntax shouldn't be used.

Julien Lebosquain
It's actually worse than just the order of execution being unspecified (which would just mean you don't know what the answer will be), in this case the behavior is undefined (so you don't know whether your computer will catch fire).
Steve Jessop
A: 

The operator priority explain the ++ operator occurs first.

Therefore: ++x occurs 3 times: then x=4 and finally: 4 + 4 + 4 = 12

Hijack: this is wrong, see thread on gamedev.net for a few explanations, and correct answer below.

as of 2007 compilers documented in gamedev thread:
VC8: x==12
Borland & GCC: x==10

yogsototh
+1 Beat me to it by 26 sec :)
foriamstu
This doesn't have to happen, the behaviour is undefined. 6 would be just as plausible a result.
Charles Bailey
-1 provably wrong
Dustin Getz
-1. Operator precedence is to do with deciding what values to apply operators to. It restricts, but does not dictate, the order of evaluation.
Artelius
@Dustin prove it
iamrohitbanga
@iamrohitbanga: The C and C++ standards say so (follow the link in Charles' post). QED.
Artelius
@yogsototh - this should NOT be true for C. Read the "C Language FAQ" book
EFraim
I am using gcc 4.3 and this seems to be correct. For me it is evaluated to 10.
Lucas
Sure compilers have it undefined, but the auth asked how can it be 12. This is an explanation of how the compiler can achieve the result asked.
Graphain
@Graphain: Undefined behaviour means that anything could happen, so any attempt at justifying logic for one particular answer is misleading. This answer erroneously suggests that the C++ grammar rules that result in the commonly inferred precedence rules somehow imply a given order of evaluation whereas they only guarantee _binding_ of operators or _grouping_ of sub-expressions for the purposes of evaluation equivalence.
Charles Bailey
Right I understand you now.
Graphain
A: 

You've got ++x three times, so that's 4, three times four is 12. The increments of x are done first, the value that this evaluates to is found later.

scragar
Nope. Nasal demons...
Drew Hall
That's what the compiler is doing. This is an explanation of how the compiler can achieve the result asked.
Graphain
@Graphain: No, you CANNOT know what a compiler has been doing, especially since the compiler was not specified by the OP. The compiler could have inserted rand() call.
EFraim
@Graphain: The OP clearly says that he **expects** a particular result. This is clearly a misunderstanding, and an explanation that might make him conclude that he should expect a different result is just misleading. In any case the explanation is incomplete if you don't add that you shouldn't expect anything here.
UncleBens
@Drew +1 for proper use of antiquated jargon... :D
Alex Feinman
@UncleBens Yep, got you.
Graphain
+9  A: 

As others have said, the C and C++ standards do not define the behaviour that this will produce.

But for those people who don't see why the standards would do such a thing, let's go through a "real world" example:

1 * 2 + 3 + 4 * 5

There's nothing wrong with calculating 1 * 2 + 3 before we calculate 4*5. Just because multiplication has a higher precedence than addition doesn't mean we need to perform all multiplication in the expression before doing any addition. In fact there are many different orders you validly could perform your calculations.

Where evaluations have side effects, different evaluation orders can affect the result. If the standard does not define the behaviour, do not rely on it.

Artelius
then what is the use of operator precedence. i don't understand your example:1*2 + 3 + 4 * 5 = (1*2) + 3 + (4*5)no?
iamrohitbanga
or a simpler example:1*2+3*4= (1*2)+(3*4)
iamrohitbanga
(1*2+3) + (4+5) == (1*2) + (3+4*5). there is more than exactly one way to sequence the execution, such that order of operations is still preserved. math is stateless, but if an operation affects state, you have to specify the sequence of execution more specifically.
Dustin Getz
what about associativity? left to right
iamrohitbanga
+1 For a better explanation sans jargon.
SDX2000
@Dustin Getz: Technically, C++ grammar specifies that the expression must be (((1*2) + 3) + (4*5)) and not ((1*2) + (3 + (4*5))) but you are right that the calculation order could be 1*2, 4*5, (1*2)+3, ((1*2) + 3) + (4*5) or 1*2, (1*2) + 3, 4*5, ((1*2) + 3) + (4*5) or a number of other possibilities including independent parts being done in parallel.
Charles Bailey
+3  A: 

The code snippet will invoke Undefined behavior in both C/C++.Read about Sequence Point from here.

nthrgeek
+1 for the link
neuro
A: 

try putting in (++x)+(++x)+(--x), (++x)+(--x)+(++x) or (--x)+(++x)+(++x)

Sabir's ex neighbour