签名功能

时间:2012-07-07 05:18:57

标签: c++

我是初级程序员,刚刚开始用C ++学习编程,

我看了一个名为“FUNCTION OVERLOADING”的功能,虽然我已经理解了代码级别的目的和实现,但我还没有理解它是如何在编译器级别实现的,即编译器如何区分具有相同名称的不同功能的签名将

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

具有相同的签名
return-type func-name (data-type 2 , data-type-1);

并且同样的事情也适用于重载的构造函数吗?

1 个答案:

答案 0 :(得分:8)

编译器使用称为name mangling的技术。

简而言之,编译器将参数的数量和类型编码为写入目标文件的实际名称。维基百科有关该主题的文章中有一些例子,包括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创建两个不同的函数(实际名称不是由语言定义,而是依赖于编译器)。我们在这个级别的程序中不能有两个同名的函数。