Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Expression priority? How this result happens?

Tags:

c++

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));
}
like image 848
newda Avatar asked Mar 29 '12 00:03

newda


2 Answers

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.

like image 85
Ed S. Avatar answered Nov 19 '22 04:11

Ed S.


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?

like image 2
Jack Avatar answered Nov 19 '22 06:11

Jack