C/C++ 標準未規定函數參數的求值順序,編譯器可自由選擇「左到右」或「右到左」。結合前置 ++a(先增後取值)與後置 a++(先取值後增)的語義差異,極易產生未定義行為(UB)或編譯器相關結果。本文透過經典案例深度解析。
int a = 15;
printf("%d,%d,%d", ++a, a++, 10 * a++);
18, 17, 150
10 * a++:a=15 → 計算 10*15=150 → a 變 16a++:a=16 → 取值 16 → a 變 17++a:a=17 → 先增為 18 → 取值 18對應輸出順序(左到右):18, 17, 150
a 在一次函數呼叫中被修改三次,標準明確規定為未定義行為++a:a = a + 1; return a;a++:tmp = a; a = a + 1; return tmp;「函數呼叫的參數求值順序未指定。……若同一標量物件在相鄰序列點之間被修改超過一次,行為未定義。」
int a = 15;
int p1 = ++a; // a=16, p1=16
int p2 = a++; // p2=16, a=17
int p3 = 10 * a++; // p3=170, a=18
printf("%d,%d,%d", p1, p2, p3); // 16,16,170 - 確定行為
; 產生序列點-Wall -Wextra -Wsequence-point / /Wall)記住:能讓人困惑的代碼,就是壞代碼。為了幾行字節數犧牲可讀性與正確性,得不償失。