2014年3月6日 星期四

Evaluation order is undefined - C

#include <iostream>
using namespace std;

class Add{
public:
    Add( int x = 0 ) : val( x ) {}
    int getVal() const {return val;}
    void setVal( int x ) {val = x;}

    Add& operator++();
private:
    int val;
};
Add& Add::operator++(){
    cout << "Increment " << val << endl;
    ++val;
    return *this;
}

Add operator +(const Add& lhs, const Add& rhs)
{
    cout << "Add " << lhs.getVal() << " and " << rhs.getVal() << "\n";
    int added = lhs.getVal();
    added = added + rhs.getVal();
    return Add(added);
}
int main( ){
    {
    Add x(10), y(20);
    ++x = ++x + ++y;
    cout << x.getVal() << endl;
    }
    cout << endl;
    {
    Add x(10), y(20);
    Add z;
    ++z = ++x + ++y;
    cout << z.getVal() << endl;
    }
    cout << endl;
    {
    Add x(10), y(20);
    ++x = ++y + ++x;
    cout << x.getVal() << endl;
    }
    return 0;
}


mingw32-g++ by Code::Blocks :
Increment 10
Increment 20
Increment 11
Add 12 and 21
33

Increment 0
Increment 20
Increment 10
Add 11 and 21
32

Increment 10
Increment 11
Increment 20
Add 21 and 12
33
1. 等號左邊 prefix increment
2. rhs increment
3. lhs increment
4. addition
5. assign

codepad output and Visual Studio 2012 ouput:
Increment 20
Increment 10
Add 11 and 21
Increment 11
32

Increment 20
Increment 10
Add 11 and 21
Increment 0
32

Increment 10
Increment 20
Add 21 and 11
Increment 11
32
1. 等號右邊 rhs increment
2. 等號右邊 lhs increment
3. addition
4. 等號左邊 prefix increment
5. assign


結論:
當一個expression中, 某一個 sub-expression 改變某另一個 sub-expression 必須用到的 operand 之值, 此種 expression 的行為是 undefined, 因為此語言未保證 left-to-right evaluation order




沒有留言:

張貼留言