2012-11-29 17 views
2

我指出了一個奇怪的gcc行爲: 當同一個指令使用同一個變量,並且當這個變量被一個函數調用(變量通過引用或指針傳遞)時,變量更改不會爲同一指令的其他函數修改。gcc:在同一條指令中使用相同var時引用參數發生變化

這是一個正常的C++行爲或boggus?
注意:優化(-O)標誌未設置。
注2:與solaris CC編譯器一起工作良好。

示範用gcc 4.5.3(Linux或mingw的/ Cygwin的)

class C { 
public: 
    const C & inc(int & i) const  
    { 
    ++i; 
    cout << "inc: i = " << i << endl; return *this; 
    } 
    const C & see(int i) const 
    {  
    cout << "see: i = " << i << endl; return *this; 
    } 
    const C & see2(const int & i) const { 
    cout << "see2: i = " << i << endl; return *this; } 
    }; 

int main() 
{ 
    C c; 
    int i = 0; 
    c.see(i).inc(i).see(i).see2(i).inc(i).see(i).see2(i); 
    c.see(i); 
    return 0; 
} 

輸出:

見:I = 0
INC中:i = 1
見:ⅰ = 0 :1 expected
see2:i = 1
inc:i = 2
看到:I = 0 :2預期
SEE2中:i = 2
見:I = 2

回答

2

的函數參數的評價順序是不確定的相對於彼此。在這種情況下,海灣合作委員會選擇評估i爲早期傳遞給see方法調用。

您的代碼就相當於:的see參數

class C {}; 
C &inc(C &c, int &i) { ++i; return c; } 
C &see(C &c, int i) { std::cout << i << '\n'; return c; } 
C c; 
int i = 0; 
see(inc(c, i), i); 

有效的評估命令是:

1. evaluate inc(...) to pass c to see(...) 
2. evaluate i as an rvalue to pass to see(...) 

1. evaluate i as an rvalue to pass to see(...) 
2. evaluate inc(...) to pass c to see(...) 

在前者的情況下,程序打印1;在後者中,它打印0

請注意,行爲是未指定但不是未定義;它必須打印01。這是因爲在調用inc之前和之後得到一個序列點;在C++ 11中,對於調用函數(1.9p15)中的評估,函數的執行是不確定的(但不是未序列化的)。

+0

@ user1863135如果您質疑'see2'的不同行爲,那是因爲參數是一個(const)引用,所以值計算(即讀取'i'的值)發生在函數內部,而不是它的參數列表。 – ecatmur

+0

然後'see(inc(c,i),i)'與'const C&x = inc(c,i)不同。見(x,i);' 對我來說,前者是後者的捷徑。但是我錯了。 – Alcolo47

0

這是正確的行爲:它沒有被標準規定,在哪個順序中執行給定語句的子表達式。在你的情況下,顯然編譯器首先執行所有i子表達式,即使得i的副本在之前將其傳遞給see(),的不同調用,然後的任何調用被評估。

相關問題