理論的には、C ++では、参照されるものは通常のポインターとして実装されます。次に、コンパイラは関数tonehaveのコードを参照のように変更しますが、アドレスをロードしてから間接的にアドレスを移動します。
これが小さなアプリケーションです:
void foo( int & value )
{
value = 3;
}
void bar( int *value )
{
*value = 3;
}
void do_test()
{
int i;
foo(i);
bar(&i);
}
それをアセンブルして、gccで生成されたアセンブル(gcc -s)を見てみましょう。
.file "test-params.cpp"
.text
.globl _Z3fooRi
.type _Z3fooRi, @function
_Z3fooRi:
.LFB0:
.cfi_startproc
.cfi_personality 0x0,__gxx_personality_v0
pushl %ebp
.cfi_def_cfa_offset 8
movl %esp, %ebp
.cfi_offset 5, -8
.cfi_def_cfa_register 5
movl 8(%ebp), %eax
movl $3, (%eax)
popl %ebp
ret
.cfi_endproc
.LFE0:
.size _Z3fooRi, .-_Z3fooRi
.globl _Z3barPi
.type _Z3barPi, @function
_Z3barPi:
.LFB1:
.cfi_startproc
.cfi_personality 0x0,__gxx_personality_v0
pushl %ebp
.cfi_def_cfa_offset 8
movl %esp, %ebp
.cfi_offset 5, -8
.cfi_def_cfa_register 5
movl 8(%ebp), %eax
movl $3, (%eax)
popl %ebp
ret
.cfi_endproc
.LFE1:
.size _Z3barPi, .-_Z3barPi
.globl _Z7do_testv
.type _Z7do_testv, @function
_Z7do_testv:
.LFB2:
.cfi_startproc
.cfi_personality 0x0,__gxx_personality_v0
pushl %ebp
.cfi_def_cfa_offset 8
movl %esp, %ebp
.cfi_offset 5, -8
.cfi_def_cfa_register 5
subl $20, %esp
leal -4(%ebp), %eax
movl %eax, (%esp)
call _Z3fooRi
leal -4(%ebp), %eax
movl %eax, (%esp)
call _Z3barPi
leave
ret
.cfi_endproc
.LFE2:
.size _Z7do_testv, .-_Z7do_testv
.ident "GCC: (Ubuntu 4.4.3-4ubuntu5) 4.4.3"
.section .note.GNU-stack,"",@progbits
ご覧のとおり、両方の関数で、コンパイラーは(stack movl 8(%ebp), %eax
)を読み取り、両方の呼び出しで、コンパイラーはアドレスをスタック(leal -4(%ebp), %eax)
。
GMan-SavetheUnicoがC宣言について与えた答えが問題かもしれません。問題はCとFortran(少なくとも使用している2つのコンパイラ)間の相互運用性にあるようです。