5

In cpp, the result of the following code snippet is: 5 5 5 But in java, the result of the same code snippet is: 3 5 7 I do not know why, is there anyone could explain it? Thanks a lot!

class H
{
  public:
    H &pr (int n, char * prompt)
    {
        cout<<prompt<<n<<" ";
        return *this;
    }

    H &fn(int n)
    {
        return pr(n,"");
    }
};

void test()
{
    int v=3;
    H h;
    h.fn(v).fn(v=5).fn((v=7));
}
K Mehta
  • 10,323
  • 4
  • 46
  • 76
newda
  • 129
  • 5

2 Answers2

6

In cpp, the result of the following code snippet is: 5 5 5 But in java, the result of the same code snippet is: 3 5 7 I do not know why,

Because C++ ain't Java :)

You are mutating the variable v in the last two function calls. Let's look at the dissassembly (debug here to see things more clearly, in release a static value of 5 is used, but it could also be 7 just as easily. You'll see why):

    h.fn(v).fn(v=5).fn((v=7));
00411565  mov         dword ptr [v],7 
0041156C  mov         dword ptr [v],5 
00411573  mov         eax,dword ptr [v] 
00411576  push        eax  

The order of expression evaluation is not guaranteed to be the order that you call the functions here. You are modifying v between sequence points. 7 gets assigned to v, then 5, then the first function is called. Note that it doesn't have to be 7 and then 5 in that order, it could be swapped! The order of evaluation is unspecified, it could be anything.

You have a chain of functions which mutate v twice. You cannot count on the fact that each mutation will occur in the order you typed it here.

We can simplify it. Let's say we have two functions; x and y that both return an int. If I write:

int k = x() + y();

There is no guarantee that x() will be called before y(). So, if you are mutating an argument common to both functions then the mutation may occur in the call to y() first, which is what you are seeing.

Ed S.
  • 122,712
  • 22
  • 185
  • 265
  • 1
    +1 To make it a bit more explicit: The program has *Undefined Behavior* by the standard, and that means that the program can basically produce any of the following outputs: 3 5 6; 3 5 5; 3 7 7; 5 5 5; 5 5 7; 5 7 7; 7 7 7 (and possibly others that I skipped in between) – David Rodríguez - dribeas Mar 29 '12 at 02:29
2

The problem here is that the standard does not guarantee how the expressions are evaluated.

Oh well, it does it partially but if you compile that code you get a specific warning that states

warning: operation on ‘v’ may be undefined

I think this question can enlighten you about this issues: Is this code well-defined?

Community
  • 1
  • 1
Jack
  • 131,802
  • 30
  • 241
  • 343