a=1)、自增(i++)、函數調用(若修改全局狀態)均產生副作用。; 結尾的語句)。&&、||、?:、,(逗號運算符)運算符求值後。y = x++ + x++int x = 1, y;
y = x++ + x++; // 未定義行為!
分析:整個賦值表達式是完整表達式,兩個 x++ 是子表達式。兩個序列點(語句開始的 ; 和結束的 ;)之間,x 被修改了兩次,違反「至多修改一次」規則。編譯器可能輸出 2、3 或其他任意值,甚至崩潰。
printf("%d", i++ * i++)許多人以為後綴 ++ 「在輸出舊值後立即執行」,實際上標準不保證自增發生的具體時刻,只保證在下一個序列點前完成。編譯器常選擇「先用舊值相乘,再統一自增」,導致 7*7=49 而非預期的 7*8=56。此類代碼行為完全未定義,切勿嘗試探究特定編譯器行為。
a[i] = i++ 非法而 i = i+1 合法?i = i+1:i 的舊值僅用於計算新值,符合「訪問僅為決定要存儲的值」。a[i] = i++:i 既被修改(右邊),又被用於計算左邊下標(非直接計算新值),屬「修改後又被引用」,未定義。&& || ?: , 保證左操作數先求值並產生副作用,若左操作數決定結果則右操作數不求值。這種強制順序使它們成為天然的序列點,可安全編寫 p && *p++ 等模式。
y = x++ + x++ → y = x + x; x += 2;-Wall -Wextra -Wsequence-point),靜態分析工具(Clang Static Analyzer, PVS-Studio)可捕獲大多數違規。