我是一个初级程序员,刚刚开始学习C++编程。
我看过一个叫做“函数重载”的特性,虽然我已经理解了它在代码级的用途和实现,但我还不知道它是如何在编译器级实现的,即编译器如何区分具有相同名称的不同函数的签名和
return-type func-name (data-type 1 , data-type-2);会有相同的签名
return-type func-name (data-type 2 , data-type-1);同样的事情也适用于重载的构造函数吗?
发布于 2012-07-07 13:20:37
编译器使用一种称为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创建两个不同的函数(实际名称不是由语言定义的,而是依赖于编译器)。在这个级别的程序中,我们不能有两个同名的函数。
https://stackoverflow.com/questions/11372476
复制相似问题