2010-06-04 80 views
1

我想下面的代碼打印11,但打印12,除了在後一種情況下,它打印10操作數的計算順序+分配副作用

x=5; x1=x+(x=6); printf("%d\n",x1); 
x=5; x1=(x=x)+(x=6); printf("%d\n",x1); 
x=5; x1=(x+0)+(x=6); printf("%d\n",x1); 
x=5; x1=(x=5)+(x=6); printf("%d\n",x1); 

x=5; x1=(x=6)+x; printf("%d\n",x1); 
x=5; x1=(x=6)+(x=x); printf("%d\n",x1); 
x=5; x1=(x=6)+(x+0); printf("%d\n",x1); 
x=5; x1=(x=6)+(x=5); printf("%d\n",x1); 

GCC在任何情況下說:「警告: 'x'上的操作可能是未定義的'。

就是這樣。

Bernhard

PS:沒有問題,對不起。感謝您的回答。 :)
PPS:實際的代碼是:

while (data-(data=read(adr)&(1<<6))) i++; 

我在ADR等6位停止切換。

+4

變異變量序列點之間兩次是un定義的行爲。因此,變異變量,然後讀取它的值。 無論您期望得到什麼樣的價值,都是無效的假設。您應該重寫代碼以符合標準。 – 2010-06-04 21:24:54

+0

[任何人都可以解釋這些未定義的行爲(i = i ++ + ++ i,i = i ++等...)](http://stackoverflow.com/questions/949433/could-anyone-explain-these- undefined-behaviors-iiiii-etc) – 2010-06-04 21:25:46

+4

結果是,如您的編譯器診斷,未定義。所以不要寫這樣的代碼。 – 2010-06-04 21:26:23

回答

2

結果未定義,不需要進一步解釋。但要說明兩種可能的方式,編譯器可以對待你的代碼:

int x = 1; 
int n = (x=3) + x; 

編譯器可以計算(X = 3)先在這種情況下,分配給n的值6.或者也可以先評估X在這種情況下,分配給n的值4

2

有警告的原因...序列點之間的評估順序未指定。

+0

序列點之間的評估順序*未指定*。 「未定義」是一個更強的術語,意味着該標準沒有規定任何有關程序任何部分的行爲。 – 2010-06-04 22:01:35

1

可以使用很少使用逗號操作,與其他變量一起,爲了寫你想要的循環:

while (lastdata = data, lastdata != (data = read(adr) & (1<<6))) i++;