実行中のコードの分解:
int i = 0;
xor edx, edx
mov dword ptr i, edx // set i = 0
i += i++;
mov eax, dword ptr i // set eax = i (=0)
mov dword ptr tempVar1, eax // set tempVar1 = eax (=0)
mov eax, dword ptr i // set eax = 0 ( again... why??? =\ )
mov dword ptr tempVar2, eax // set tempVar2 = eax (=0)
inc dword ptr i // set i = i+1 (=1)
mov eax, dword ptr tempVar1 // set eax = tempVar1 (=0)
add eax, dword ptr tempVar2 // set eax = eax+tempVar2 (=0)
mov dword ptr i, eax // set i = eax (=0)
同等のコード
次のコードと同じコードにコンパイルされます。
int i, tempVar1, tempVar2;
i = 0;
tempVar1 = i; // created due to postfix ++ operator
tempVar2 = i; // created due to += operator
++i;
i = tempVar1 + tempVar2;
2 番目のコードの逆アセンブル (同じであることを証明するため)
int i, tempVar1, tempVar2;
i = 0;
xor edx, edx
mov dword ptr i, edx
tempVar1 = i; // created due to postfix ++ operator
mov eax, dword ptr i
mov dword ptr tempVar1, eax
tempVar2 = i; // created due to += operator
mov eax, dword ptr i
mov dword ptr tempVar2, eax
++i;
inc dword ptr i
i = tempVar1 + tempVar2;
mov eax, dword ptr tempVar1
add eax, dword ptr tempVar2
mov dword ptr i, eax
分解ウィンドウを開く
ほとんどの人は、Visual Studio の [逆アセンブリ]ウィンドウを使用して最終的なインメモリ アセンブリ コードを表示できることを知らないか、覚えていません。実行されているマシンコードを示していますが、CIL ではありません。
デバッグ中にこれを使用します。
Debug (menu) -> Windows (submenu) -> Disassembly
では、postfix++ で何が起こっているのでしょうか?
postfix++ は、評価後にオペランドの値をインクリメントしたいことを示しています...誰もが知っている...少し混乱しているのは、「評価後」の意味です。
では、「評価後」とは次のことを意味します。
- コードの同じ行でのオペランドの他の使用法は、影響を受ける必要があります。
a = i++ + i
2 番目の i はインクリメントの影響を受けます
Func(i++, i)
2番目の私は影響を受けます
||
同じ行の他の使用法は、 andのような短絡演算子を尊重し&&
ます:
(false && i++ != i) || i == 0
3 番目の i は評価されないため、i++ の影響を受けません。
では、次の意味は何ですか: i += i++;
?
と同じですi = i + i++;
評価の順序は次のとおりです。
- i + i (つまり 0 + 0) を格納します。
- i をインクリメントする (i が 1 になる)
- ステップ 1 の値を i に割り当てます (i は 0 になります)
増分が破棄されているわけではありません。
の意味は何ですか: i = i++ + i;
?
これは前の例と同じではありません。3番目i
はインクリメントの影響を受けます。
評価の順序は次のとおりです。
- i を格納 (つまり 0)
- i をインクリメントする (i が 1 になる)
- ステップ 1 + i (つまり 0 + 1) の値を格納します。
- ステップ 3 の値を i に代入します (i は 1 になります)