理论上,在 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 - Save the Unico 给出的关于 C 声明的答案可能是问题所在。似乎问题在于 C 和 fortran 之间的互操作性(至少您正在使用的这两个编译器)。