【发布时间】:2019-06-27 03:25:37
【问题描述】:
为什么我们在函数名上使用 & 符号:https://elixir.bootlin.com/linux/v4.0/source/arch/x86/kernel/traps.c#L991?符号system_call 是一个函数,因此变量的内容已经是一个内存地址。为什么要使用&符号来获取它的地址?比如我写了这个测试程序:
#include <stdio.h>
int receiver(void *);
int test() {
}
int main() {
printf("%p %p\n", test, &test);
receiver(test);
receiver(&test);
}
int receiver(void *p) {
printf("receiver %p\n", p);
}
输出是:
0x556baeada6b0 0x556baeada6b0
receiver 0x556baeada6b0
receiver 0x556baeada6b0
使用 & 符号似乎没有任何作用。
更多,如果我使用
objdump -d .text test
结果如下:
00000000000006b7 <main>:
6b7: 55 push %rbp
6b8: 48 89 e5 mov %rsp,%rbp
6bb: 48 8d 15 ee ff ff ff lea -0x12(%rip),%rdx # 6b0 <test>
6c2: 48 8d 35 e7 ff ff ff lea -0x19(%rip),%rsi # 6b0 <test>
6c9: 48 8d 3d d4 00 00 00 lea 0xd4(%rip),%rdi # 7a4 <_IO_stdin_used+0x4>
6d0: b8 00 00 00 00 mov $0x0,%eax
6d5: e8 86 fe ff ff callq 560 <printf@plt>
6da: 48 8d 3d cf ff ff ff lea -0x31(%rip),%rdi # 6b0 <test>
6e1: e8 13 00 00 00 callq 6f9 <receiver>
6e6: 48 8d 3d c3 ff ff ff lea -0x3d(%rip),%rdi # 6b0 <test>
6ed: e8 07 00 00 00 callq 6f9 <receiver>
6f2: b8 00 00 00 00 mov $0x0,%eax
6f7: 5d pop %rbp
6f8: c3 retq
正如您在6bb 和6c2 上看到的那样,test 的地址被移动到具有相同 lea 指令的寄存器中。此外,在6da 和6e6 上使用了相同的 lea 指令。即使在机器代码级别上,使用与号似乎也没有任何区别。
【问题讨论】:
-
Why do function pointer definitions work with any number of ampersands '&' or asterisks '*'? 的可能重复项(虽然它在技术上没有回答 why 您链接到的代码的作者选择使用
&而不是省略它,除非找到作者并询问他们,否则该问题可能无法回答。)
标签: c