2013-06-18 46 views
3

a[i]=i++;的聲明是不確定的,因爲有一個混淆,即i(舊的或新的)值用於評估左側以獲得L-value。如果使用-Wall進行編譯,此編譯器將給出警告(操作..可能未定義)。爲什麼在C中提到的代碼是未定義的行爲

在下面的代碼,在聲明中x->a = x->b, ++x++->b;
x正在被改變,並在左側用它來獲得L-value。對於這個語句,如果使用-Wall執行,編譯器不會給出任何警告。

有人能解釋爲什麼這不是未定義的行爲? 謝謝!

struct Data { 
int a; 
int b; 
} y[4] = { 10, 20, 30, 40}; 

struct Data *x = y; 
int i; 

for(i=0; i<2; i++) { 
    x->a = x->b, ++x++->b; 
    printf("%d %d\t", y[i].a, y[i].b); 
} 
+5

僅僅因爲編譯器沒有警告,並不意味着這個行爲真的很好定義。 –

回答

12

逗號操作符具有最低的優先級,

表達:
賦值表達式
表達,賦值表達式

所以

x->a = x->b, ++x++->b; 

實際上是

(x->a = x->b), ++(x++->b); 

和逗號運算符是一個順序點,因此兩個修改x進行測序,並且沒有未定義的行爲。

+1

對,我錯過了。如果語句x-> a = ++ x ++ - > b,它將是未定義的;謝謝 – mandeep

7

x->a = x->b, ++x++->b;不調用未定義的行爲。逗號運算符具有比賦值操作符的優先級低,所以該代碼相當於:

x->a = x->b; 
++x++->b; 

在第二行中出現,後綴++操作者修改x,並且前綴++操作者修改的構件b取消結構。沒有序列點規則被侵犯。

+1

明確定義和明確的證明不一定是一回事。 – chepner

相關問題