程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> 為什麼f(i = -1, i = -1)是未定義行為?

為什麼f(i = -1, i = -1)是未定義行為?

編輯:C++入門知識

問題:

最近在讀 order of evaluation violations,其中的一個例子使我很困惑。

1)如果對一個標量對象的副作用相對於對這個標量對象的另一個副作用是無序的,那麼這是未定義行為。

  1. //代碼片段  
  2. 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之前是無序的,那麼存在兩種可能性:

  • 預估A和B是無序的:它們可能以任意的順序運行並且可能會重疊在一個線程的執行中,編譯器可能會交錯組織包含A和B的CPU指令)。
  • 預估A和B是無法確定的順序:它們可能以任意順序運行但是一定不會重疊。或者A在B執行之前完成或者B在A執行之前完成。下一次執行同樣的語句時,執行的順序有可能是相反的。

假設運算執行後,把-1存進一個內存地址,就這個行為自身而言,這似乎並不會引發任何問題。但是如果一個指令和另一個指令交錯執行操作同一個內存地址,你不能說編譯器不會把這些指令優化成一個獨立的具有同樣效果的指令集,這樣就會出錯了。

例如,假想把內存清零然後再遞減是最高效的。現在開始值是-1,然後就是:

  1. 1 f(i=-1,i=-1)   

也許會變成:

  1. clear i //清空 i  
  2. clear i //清空 i  
  3. decr i //遞減 i  
  4. decr i //遞減 i 

現在i是-2。

這也許是一個假的例子,但可能是真的。

譯文鏈接: http://blog.jobbole.com/62650/

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved