签名功能

Aru*_*mar 3 c++

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

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

return-type func-name (data-type 1 , data-type-2);
Run Code Online (Sandbox Code Playgroud)

会有同样的签名

return-type func-name (data-type 2 , data-type-1);
Run Code Online (Sandbox Code Playgroud)

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

Ray*_*oal 8

编译器使用称为名称修改的技术.

简而言之,编译器将参数的数量和类型编码为写入目标文件的实际名称.关于这个主题的维基百科文章中有一些例子,包括C++的例子.

作为一个具体的例子,我在Mac上使用g ++来编译以下C++文件:

TEST.CPP

int f(int x) {}

int f(double x, char y) {}
Run Code Online (Sandbox Code Playgroud)

g++ -S test.cpp
Run Code Online (Sandbox Code Playgroud)

这导致汇编语言文件(略微省略):

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
Run Code Online (Sandbox Code Playgroud)

这里的重要部分是调用函数,__Z1fi__Z1fdc在汇编语言输出中,链接器将看到它们.你可以推断这f是函数的名称,对于参数,我们有i(int)和dc(double和char).请注意,参数的顺序也是编码的!

现在考虑如果你有的话会发生什么

int f(int x) {}
int f(int y) {}
Run Code Online (Sandbox Code Playgroud)

就语言而言,这当然不是一个可接受的情况,因为f(10)无法解决这样的呼叫.从理论上讲,语言可以指定第二个声明替换第一个声明,但C++不会这样做.这只是一种非法的超载.

事实证明,名称修改实际上显示了为什么这应该是一个错误.编译器会尝试使用名称创建两个不同的函数__Z1fi(实际名称不是由语言定义,而是依赖于编译器).在这个级别的程序中,我们不能有两个具有相同名称的函数.