3

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

Why this code is generating 8 as a result ?

#include <iostream> 
using namespace  std ;
void myFunction(int i)
{
    i = i + 2 + ++i;
    cout<<i<<endl;
}

void main () 
{
    int i = 2;
    myFunction(i);
    cin>> i;
}

I think the result should be 7 not 8...I am using Visual Studio 2008

Community
  • 1
  • 1
Mohamad Alhamoud
  • 4,881
  • 9
  • 33
  • 44

5 Answers5

18

The order of evaluation of terms on the right hand side of this expression

i = i + 2 + ++i;

is undefined. i.e. they can occur in any order. In this case the compiler has chosen to increment i first (++i, third term), before evaluating i (first term), which results in 3 + 2 + 3.

Dijkstra
  • 2,490
  • 3
  • 21
  • 35
  • 8
    Actually, the whole behavior is undefined, and the compiler would be conforming to the Standard in evaluating the expression to 42. – David Thornley Nov 02 '10 at 19:39
  • 3
    Undefined behaviour is awesome (for compiler developers) :) – Dijkstra Nov 02 '10 at 19:41
  • @Dijkstra: For a compiler developer, undefined behavior means never having to admit you made a mistake, and testing for acceptable output is a snap. – David Thornley Nov 02 '10 at 19:45
  • Is this really undefined? Doesn't it perform the highest precedent operation (preincrement), so now i=3 then the addition with left to right associativity, (i+2)+i, giving the value of 8? – John Gordon Nov 02 '10 at 19:51
  • @John: Nope, it's undefined. What you're saying is a pretty good guess at how the compiler will probably evaluate it in practice. But it's not required to do so, it may vary from compiler to compiler, and the compiler may even apply optimizations that change the result – jalf Nov 02 '10 at 19:53
  • OK, but why? Why aren't the operations required to be performed in the order of precedence as I described? How can I recognize other places where the behavior is undefined? – John Gordon Nov 02 '10 at 19:55
  • 1
    @John: The precedence of operator ++ only applies to the expression (++i). Precedence demands that the increment will happen before the expression is added to (i + 2), but it doesn't demand that the increment happens before the value of the first i is assessed. – Benjamin Lindley Nov 02 '10 at 19:59
  • @John Gorden: Anywhere a variable is updated more than once in statement is BAD. Re-write as `++i; i = (i -1) + 2 + i;` now it is well defined. Any arithmetic expression that makes you think whats happening here; should be re-factored to make it easy to read for humans. – Martin York Nov 02 '10 at 21:24
13

You are changing i twice in one statement, and also referencing its value in a way not connected to changing it. This is undefined behavior, and there is no single right answer.

David Thornley
  • 56,304
  • 9
  • 91
  • 158
  • 3
    or you could say there is an infinite number of right answers, but no *wrong* answer. ;) – jalf Nov 02 '10 at 19:42
  • is this going to happen in c++ only ? – Mohamad Alhamoud Nov 02 '10 at 19:44
  • it's also undefined in C – David Gelhar Nov 02 '10 at 19:47
  • @M.H.: C++ and C. Other languages have rules that can make expressions like this clearly defined. I believe the next C++ standard will have rules defining more such expressions, but I haven't researched it yet, and VS2008 is still on the current standard. – David Thornley Nov 02 '10 at 19:48
  • 1
    @M.H: If you write code like this your co-workers are going to come and bash you on the head even if it is well defined. Because the rule that makes it well defined will be so obscure that nobody actually knows it priceless (they heard from a friends cousin twice removed sisters husband that it does X). Code should be easy to read for everybody from beginner to expert. Otherwise it is unmaintainable and by definition BAD (as in dog). – Martin York Nov 02 '10 at 21:31
4

Unspecified behavior. It could be any value. You're not allowed to modify a variable more than once in a single sequence point.

Edward Strange
  • 40,307
  • 7
  • 73
  • 125
-1

The ++i is executed before all other statements are, so in the line i + 2 + ++i the result is (with i=2) 3 + 2 + 3 which is 8.

Burton Samograd
  • 3,652
  • 19
  • 21
-1

It's evaluating "++i" first. "i" is then 3 so you end up with 3 + 2 + 3 = 8. This is an excellent example of why you should be careful with operators!

Jay
  • 13,803
  • 4
  • 42
  • 69