問題:
最近在讀 order of evaluation violations,其中的一個例子使我很困惑。
1)如果對一個標量對象的副作用相對於對這個標量對象的另一個副作用是無序的,那麼這是未定義行為。
- //代碼片段
- f(i=-1,i=-1);//undefined behavior 未定義行為
在這段代碼中,很明顯 i 是一個標量對象。
算術類型3.9.1),枚舉類型,指針類型,指針成員類型3.9.2),空指針類型和被const或volatile修飾的類型3.9.3)等統稱為標量類型。
從這句話中我看不出上面那句代碼有什麼分歧的地方。我認為不論第一個參數還是第二個參數先執行,i最終都是-1,並且兩個參數的值都是-1。
有人能解釋清楚這些嗎?
最佳答案:
既然運算是無序的,也就不能說分配任務的指令不能交錯執行。也許會選擇最佳的方式去運行,由CPU的架構來決定。引用下面這句話來說明:
如果A在B之前是無序的並且B在A之前是無序的,那麼存在兩種可能性:
假設運算執行後,把-1存進一個內存地址,就這個行為自身而言,這似乎並不會引發任何問題。但是如果一個指令和另一個指令交錯執行操作同一個內存地址,你不能說編譯器不會把這些指令優化成一個獨立的具有同樣效果的指令集,這樣就會出錯了。
例如,假想把內存清零然後再遞減是最高效的。現在開始值是-1,然後就是:
- 1 f(i=-1,i=-1)
也許會變成:
- clear i //清空 i
- clear i //清空 i
- decr i //遞減 i
- decr i //遞減 i
現在i是-2。
這也許是一個假的例子,但可能是真的。
譯文鏈接: http://blog.jobbole.com/62650/