int i = 0;
int a[] = {10, 20, 30};
int r = 1 * a[i++] + 2 * a[i++] + 3 * a[i++];
printf("%d\n", r); // GCC 4.7.3 輸出 60
C 標準 (C11 6.5/2) 規定:若同一表達式中對同一標量物件進行多次修改,或修改後又讀取其值 (非為了決定新值),行為未定義。
此處 i 在同一表達式中被修改三次 (i++),且其值被用於陣列索引,屬於多次修改且讀取值不為決定新值 → UB。
反組譯顯示:三次 a[i++] 皆在 i 遞增前使用 i=0,即皆取 a[0]=10。
計算:1*10 + 2*10 + 3*10 = 60。
三次遞增指令集中在表達式計算完成後執行。
i++ 的遞增)。;、函數呼叫前後、&&/||/?:/, 運算子)。int i = 0;
int r = 1 * a[i] + 2 * a[i+1] + 3 * a[i+2];
i += 3; // 明確分離修改與讀取
-Wall -Wextra -Wsequence-point (GCC/Clang)。理解 UB 是寫出健壯 C 程式的關鍵,切勿依賴特定編譯器行為。