2010-10-13 42 views
3

此代碼段必須返回什麼? 16 16 16是嗎?奇怪的「+ =」行爲

int main(int argc,char *argv[]) 
{ 
    int a=2,*f1,*f2; 
    f1=f2=&a; 
    *f2+=*f1+=a+=2.5; 
    printf("%d %d %d\n",a,*f1,*f2); 
    return 0; 
} 

奇怪的是,它返回8 8 8給我? :-(

+2

誰讓你編寫代碼?!? – ruslik 2010-10-13 14:23:42

+0

提問者也許不知道,但這是另一個微妙的變種http://stackoverflow.com/questions/949433/could-anyone-explain-these-undefined-behaviors-i-i-i-i-i-i-c0 – 2010-10-13 14:26:16

+0

什麼是怪物?你的老師是否喜歡在背後刺傷好的習慣?這種行爲甚至沒有定義/保證xD – slezica 2010-10-13 14:28:58

回答

3

爲了實際瞭解此問題,請嘗試comp.lang.c FAQ有關sequence points的文章。

+0

哦!儘管我從來沒有遇到任何問題,但我從來沒有想過這一點,但知道事情未定義(或未指定)行爲總是很好的。特別是,因爲在實踐中,我已經意識到存在某種順序點,但不知道它們被記錄。很好的解釋! – StormByte 2012-04-10 02:06:11

3

*f2+=*f1+=a+=2.5;

老一套未定義行爲。

+3

@Prasoon:如果我開始懷疑,你已經寫了一個機器人來掃描新的問題的實例,並迅速提醒你有機會快速加載點,然後你應該完全提交給海灣合作委員會使用發出警告關於狡猾的代碼;-) – 2010-10-13 14:28:13

+0

@Steve:做它CW [沒有更多現在就代表這個人]。 – 2010-10-13 14:34:45

+0

@Steve:不,他可能只是給所有這些人教C,而且他們在課程開始時都聽得很清楚,他告訴他們SO是一個很好的地方,可以得到所有答案,然後成爲他們的一部分當他教他們UB時慢慢入睡。 – 2010-10-13 14:36:56

3

這是不確定的行爲,因爲a值在分配該字符串修改不止一次。所以,你可能想到的是毫無意義的。

3

根據規格6.5/2,這是未定義的行爲,因爲您在序列點之間多次修改對象:

在上一個和下一個 序列點之間,對象 最多通過評估 表達式將其存儲值修改爲 。此外,前面的 值應爲只讀,以確定要存儲的值爲 。

+0

而且由於行爲是未定義的,*任何*結果都是可能的,無論它看起來是否有意義。 – 2010-10-13 14:47:46

0

看來,它翻譯成

*f2 += 2; 
*f1 += 2; 
    a += 2.5; 

+=並非如此傳遞爲=

+0

它與「a + = a + = a + = 2.5」基本相同,這在鼻惡魔領域非常好。 – Vatine 2010-10-13 14:51:57