函数签名

3
我是一名初级程序员,刚开始学习C++编程语言。我了解了一个名为“函数重载”的特性,虽然我已经理解了其在代码层面的目的和实现方式,但我还不明白它是如何在编译器层面实现的,即编译器如何区分具有相同名称但签名不同的不同函数。
return-type func-name (data-type 1 , data-type-2);

将具有相同的签名

return-type func-name (data-type 2 , data-type-1);

对于重载的构造函数,是否也适用相同的规则呢?

您可以接受下面的最佳答案,这是本网站的规定。^_^ - prehistoricpenguin
1个回答

9
编译器使用一种称为名称修饰的技术。
简单来说,编译器将参数的数量和类型编码到写入目标文件的实际名称中。在维基百科的相关文章中有一些例子,包括C++的例子。
作为一个具体的例子,我已经在Mac上使用g++编译了以下C++文件:

test.cpp

int f(int x) {}

int f(double x, char y) {}

使用

g++ -S test.cpp

这将生成汇编语言文件(有所省略):

test.s

.globl __Z1fi
__Z1fi:
    pushq   %rbp
    movq    %rsp, %rbp
    movl    %edi, -4(%rbp)
    leave
    ret
.globl __Z1fdc
__Z1fdc:
    pushq   %rbp
    movq    %rsp, %rbp
    movsd   %xmm0, -8(%rbp)
    movb    %dil, -12(%rbp)
    leave
    ret

重要的是,在汇编语言输出中,函数被称为__Z1fi__Z1fdc,链接器将看到这些内容。您可能可以推断出f是函数的名称,而对于参数,我们有i(int)和dc(double和char)。请注意,参数顺序也被编码了!现在考虑如果您有以下代码会发生什么
int f(int x) {}
int f(int y) {}

这显然是不可接受的语言问题,因为像 f(10) 这样的调用无法解析。从理论上讲,一种语言可以指定第二个声明替换第一个声明,但 C++ 并没有这样做。这只是一种非法的重载。
事实证明,名称修饰实际上说明了为什么这应该是一个错误。编译器会尝试使用名称 __Z1fi 来创建两个不同的函数(实际名称未由语言定义,而是由编译器决定)。在此级别上,我们不能在程序中拥有两个完全相同的函数名。

1
@ArunKumar - 如果你同意它已经回答了问题,请接受答案。这是在 SO 上的正确方式。 - go4sri

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接