首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

C/C++ 自增自減副作用:序列點規則與編譯器差異的權威解讀

     編輯:程式設計綜合問答

核心結論

表達式中對同一變量多次修改、或修改後又讀取,行為未定義 (UB)。不同編譯器 (VC6/TC/VS/GCC) 結果不同,甚至同一編譯器不同優化等級結果不同。

經典 UB 示例

int i = 1;
i = i++ + ++i * i--;  // 未定義行為
printf("%d", i);      // 可能輸出任意值,甚至格式化硬盤(理論上)

C++17 規則變更(關鍵)

  • 右值引用賦值:`a = b` 中 `b` 的求值**順序於** `a` 的賦值**之前**。
  • 移位運算符:`a << b << c` 左到右求值。
  • 但 **`i++ + i++` 仍是 UB**,因為對 `i` 兩次修改無序列點隔離。

考試/面試必會的「安全」題型

工程原則

  1. **一條語句只對一個變量做一次修改**。
  2. 需要連續自增時,拆分語句:`i++; j = i + i;`。
  3. 開啟編譯器警告:`-Wall -Wextra -Wsequence-point` (GCC/Clang) 或 `/Wall` (MSVC)。
  4. 閱讀權威資料:C++ 運算符優先級與副作用深度解析、序列點與未定義行為。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
表達式結果解析
`int i=1; i = i++;`**UB**修改與讀取無序列點
`int i=1; int j = i++ + i++;`**UB**兩次修改 i
`int i=1; int j = ++i + ++i;`**UB**兩次修改 i
`int i=1; int j = i++ + 1;`j=2, i=2單次修改,安全
`int a=1; int b = a++ + ++a;`**UB**修改 a 兩次