そういえば1歳年とってた。ぬー。
ちなみにインクリメント演算子は前置のほうが早いそうです。
ほんとかなー?
こんなコードを書いた。
#include <stdio.h> int prev(){static int i=0; return ++i;} int back(){static int i=0; return i++;} void main(){ int ret_prev=0, ret_back=0; int i; puts("start"); ret_prev = prev(); ret_back = back(); printf("prev, back: %d, %d\n", ret_prev, ret_back); puts("end"); for(i=0; i<3; ++i) puts("a"); for(i=0; i<3; i++) puts("a"); }
結果
start
prev, back: 1, 0
end
a
a
a
a
a
a
これを、最適化オプションをつけずにGCC4.4.0でコンパイル。
デバッガで処理を追いかけてみる。
// prev 004013B0 /$ 55 PUSH EBP 004013B1 |. 89E5 MOV EBP,ESP 004013B3 |. A1 40404000 MOV EAX,DWORD PTR DS:[404040] 004013B8 |. 40 INC EAX 004013B9 |. A3 40404000 MOV DWORD PTR DS:[404040],EAX 004013BE |. A1 40404000 MOV EAX,DWORD PTR DS:[404040] 004013C3 |. C9 LEAVE 004013C4 \. C3 RETN // back 004013C5 /$ 55 PUSH EBP 004013C6 |. 89E5 MOV EBP,ESP 004013C8 |. A1 30404000 MOV EAX,DWORD PTR DS:[404030] 004013CD |. 89C2 MOV EDX,EAX 004013CF |. 40 INC EAX 004013D0 |. A3 30404000 MOV DWORD PTR DS:[404030],EAX 004013D5 |. 89D0 MOV EAX,EDX 004013D7 |. C9 LEAVE 004013D8 \. C3 RETN // 前置ループ 0040143D |. C74424 1C 0000>MOV DWORD PTR SS:[ESP+1C],0 // 初期化 00401445 |. EB 10 JMP SHORT func.00401457 // 条件判定までジャンプ 00401447 |> C70424 8230400>/MOV DWORD PTR SS:[ESP],func.00403082 ; | 0040144E |. E8 59020000 |CALL; \puts 00401453 |. FF4424 1C |INC DWORD PTR SS:[ESP+1C] // 変数を1増加 00401457 |> 837C24 1C 02 CMP DWORD PTR SS:[ESP+1C],2 // 変数と2と比較 0040145C |.^7E E9 \JLE SHORT func.00401447 // 2以下なら00401447までjump // 後置ループ 0040145E |. C74424 1C 0000>MOV DWORD PTR SS:[ESP+1C],0 // 初期化 00401466 |. EB 10 JMP SHORT func.00401478 // 条件判定までジャンプ 00401468 |> C70424 8230400>/MOV DWORD PTR SS:[ESP],func.00403082 ; | 0040146F |. E8 38020000 |CALL ; \puts 00401474 |. FF4424 1C |INC DWORD PTR SS:[ESP+1C] // 変数を1増加 00401478 |> 837C24 1C 02 CMP DWORD PTR SS:[ESP+1C],2 // 変数と2と比較 0040147D |.^7E E9 \JLE SHORT func.00401468 // 2以下なら00401468までjump
関数でインクリメントの返り値を受け取るときは、前置のほうが1ステップだけ減ってます。
ただ、ループ中に使う場合はどちらも同じです。
つまりインクリメントの結果を受け取る時にこの差が出るんだと思います。
一応、書いておきますが、インクリメント演算子の前置と後置では動作が異なります。
余談
インクリメント用の命令があるんだね。ちなみにデクリメントの命令もあります。
i<3の比較をすると、コンパイラを通したバイナリではi<=2に置き換わってた。
JL命令があるんだから使えばいいのになんでだろう。
定数で比較するときはこっちのほうが効率がいいのかな。