考試與刷題中常見的 n = (++i) + (++i) + (++i); 這類自增運算組合表達式,雖然在工程實踐中極少出現(且屬於未定義行為),但理解編譯器如何將其轉換為機器碼,有助於深入掌握程式碼生成機制。本文以 Visual Studio 2003 .NET 為例,透過反組譯碼逐步還原執行流程。
#include <stdio.h>
int main() {
int i = 0, n = 0;
n = (++i) + (++i) + (++i);
printf(" n = %d\n", n);
printf(" i = %d\n", i);
return 0;
}
編譯執行結果:n = 9, i = 3
int i=0, n = 0;
00411A4E mov dword ptr [i], 0 ; i 初始化為 0
00411A55 mov dword ptr [n], 0 ; n 初始化為 0
n = (++i) + (++i) + (++i);
00411A5C mov eax, dword ptr [i] ; eax = 0
00411A5F add eax, 1 ; eax = 1 (第一次 ++i)
00411A62 mov dword ptr [i], eax ; i = 1
00411A65 mov ecx, dword ptr [i] ; ecx = 1
00411A68 add ecx, 1 ; ecx = 2 (第二次 ++i)
00411A6B mov dword ptr [i], ecx ; i = 2
00411A6E mov edx, dword ptr [i] ; edx = 2
00411A71 add edx, 1 ; edx = 3 (第三次 ++i)
00411A74 mov dword ptr [i], edx ; i = 3
00411A77 mov eax, dword ptr [i] ; eax = 3
00411A7A add eax, dword ptr [i] ; eax = 3 + 3 = 6
00411A7D add eax, dword ptr [i] ; eax = 6 + 3 = 9
00411A80 mov dword ptr [n], eax ; n = 9
++i,使 i 從 0 遞增至 3。i 值(3)相加三次,得 9。反組譯碼清晰揭示了該編譯器的處理邏輯:先完成所有副作用(自增),再進行值運算。但切記:
透過反組譯分析,我們不僅能理解特定編譯器的行為,更能養成閱讀底層碼、排查疑難雜症的能力。