【问题标题】:Why do we use ampersand on a function name? [duplicate]为什么我们在函数名上使用 & 符号? [复制]
【发布时间】: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

正如您在6bb6c2 上看到的那样,test 的地址被移动到具有相同 lea 指令的寄存器中。此外,在6da6e6 上使用了相同的 lea 指令。即使在机器代码级别上,使用与号似乎也没有任何区别。

【问题讨论】:

标签: c


【解决方案1】:

在表达式中使用时(不是作为&amp; 的操作数),任何函数类型的表达式(例如您的示例中的test)都会自动转换为函数的地址。

这在C standard 的第 6.3.2.1p4 节中有规定:

函数指示符是具有函数类型的表达式。 除非它是 sizeof 运算符的操作数,否则 _Alignof 运算符,或一元 &amp; 运算符,类型为“函数返回类型”的函数指示符转换为表达式 具有“指向函数返回类型的指针”类型。

所以&amp;testtest 的计算结果相同,*test**test***test 等也一样。

【讨论】:

猜你喜欢
  • 2017-02-15
  • 2015-11-21
  • 2015-03-19
  • 1970-01-01
  • 2020-11-15
  • 2020-01-29
  • 2012-09-26
  • 2018-01-26
  • 1970-01-01
相关资源
最近更新 更多