num の値をインクリメントすることが唯一の目的である場合、1 番目と 2 番目のメソッドは同じ意図した結果を呼び出し先メソッドにもたらします。
ただし、コードを次のように変更すると、gcc によって生成されたコード (アセンブリ レベルのコード) との違いがわかります。
struct my_struct
{
int num;
};
void foo(struct my_struct* my_ptr)
{
printf("\nPost Increment: %d", my_ptr->num++);
}
int main()
{
struct my_struct a;
a.num = 10;
foo(&a);
}
次を使用してコンパイルします: gcc -masm=intel -S structTest.c -o structTest.s これは、アセンブリ コードを生成するように gcc に要求します。
テキスト エディターで structTest.s を開きます。
foo:
.LFB0:
push rbp
mov rbp, rsp
sub rsp, 16
**mov QWORD PTR [rbp-8], rdi**
mov rax, QWORD PTR [rbp-8]
mov eax, DWORD PTR [rax]
mov edx, eax
**lea ecx, [rax+1]**
mov rax, QWORD PTR [rbp-8]
mov DWORD PTR [rax], ecx
mov eax, OFFSET FLAT:.LC0
mov esi, edx
mov rdi, rax
mov eax, 0
call printf
leave
ret
.cfi_endproc
main:
.LFB1:
push rbp
mov rbp, rsp
sub rsp, 16
**mov DWORD PTR [rbp-16], 10
lea rax, [rbp-16]
mov rdi, rax
call foo**
leave
ret
.cfi_endproc
また、操作をプリインクリメントに変更すると、次のコードが生成されます。
foo:
.LFB0:
.cfi_startproc
push rbp
mov rbp, rsp
sub rsp, 16
**mov QWORD PTR [rbp-8], rdi**
mov rax, QWORD PTR [rbp-8]
mov eax, DWORD PTR [rax]
**lea edx, [rax+1]**
mov rax, QWORD PTR [rbp-8]
**mov DWORD PTR [rax], edx**
mov rax, QWORD PTR [rbp-8]
**mov edx, DWORD PTR [rax]**
mov eax, OFFSET FLAT:.LC0
mov esi, edx
mov rdi, rax
mov eax, 0
call printf
leave
ret
.cfi_endproc
したがって、2 番目のケースでは、コンパイラが num 値をインクリメントし、この num 値を printf() に渡すことがわかります。
パフォーマンスの面では、ポストインクリメントがより効率的であると期待しています。これは、メモリ位置に触れる回数が少ないためです。
上記のコードでは、重要な行は ** の間にマークされています。