未定義的行為 i i

2021-09-28 23:26:00 字數 965 閱讀 1135

i=i++;

1: 先算出左邊的值,置為0;

2: 執行i++;的+1操作.

3: 將左邊的值賦給i.

2和3在不同編譯器中經過優化後有不同的執行順序。所以執行後i可能是0,可能是1.

能執行不代表是正確的。

這種寫法,是c標準嚴格禁止的。

c標準裡,叫做未定義行為。

在c/c++中,為了少寫一行**、或者為了和某條彙編語句對應,這顆語法糖就被加進去了。因為和正規意義上的表示式不同,這種東西的***發生時機,會深刻改變程式的執行結果。

當編譯器為c表示式生成機器碼時,會偷偷做很多優化動作,以盡量加快程式執行速度。

怎麼保證這些優化動作是對的、沒有優化出錯誤呢?這就要靠c標準來規範了。

c標準委員:不規定i++的正確結果是什麼樣子(這就是「未定義行為」的含義),

編譯器折騰成啥都沒關係——哪怕你去格他的硬碟,也是符合標準的。

序列點就是類似c/c++裡面, ; 這樣的符號,(函式中引數分割的逗號不算)

每乙個序列點結束時,必須有乙個確定的狀態,但可以不限定每個序列中的過程。

//如果限定了執行細節,那麼在某些機器上可能就會變得很慢、

//或者導致一些優化演算法失效,加大編譯器實現的難度。

也就是說允許編譯器可以隨意改序列中的執行順序以實現演算法上的優化。

但,對i=i++來說,如果不規定每一拍內部的執行細節,那麼就可以有很多很多種不同結果。

最終,c/c++委員會的決定是:任何類似的寫法都不予支援。

如果有人這麼做了,那麼編譯器輸出任何結果都是合法的。

按照規定,這種非法**,執行結果是無法確定的。編譯器為其生成任何**都合法。

所以,現實是,不同編譯器、同乙個編譯器的不同版本、相同版本編譯器使用不同編譯引數,結果都可能不同。

c c 中的未定義行為

這些行為多數和c c 標準當中的定義不明確有關係 標準當中,只有四個運算元有過明確的執行順序 邏輯運算子 和 從左到右,短路測試 條件運算子 先執行?前面的表示式 逗號運算子,從左到右 其他的運算子,都沒有定義執行順序,也就是說 v f1 f2 這個表示式,f1 和f2 誰先執行是未定義的 例如 v...

js報未定義 JS的未定義和undefined

background if window else console.log server side rendering 當我啟專案的時候,不斷的報錯 window is not defined 原因在js中,有一種錯誤是 referenceerror x is not defined 造成這種錯誤出...

未定義的索引 php中 php的未定義索引如何解決

通常出現未定義的索引問題是由於陣列沒有這個值造成的,陣列分為關聯陣列和索引陣列,索引陣列是數字下標 關聯陣列是鍵值下標。解決辦法 判斷陣列中是否包含下標鍵值為id的值,如果沒有,則返回錯誤資訊,如何判斷呢,最簡單的方法就是用函式isset來判斷,如isset post id 存在則返回true,反之...