首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >函数的签名

函数的签名
EN

Stack Overflow用户
提问于 2012-07-07 13:18:57
回答 1查看 143关注 0票数 3

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

我看过一个叫做“函数重载”的特性,虽然我已经理解了它在代码级的用途和实现,但我还不知道它是如何在编译器级实现的,即编译器如何区分具有相同名称的不同函数的签名和

代码语言:javascript
复制
return-type func-name (data-type 1 , data-type-2);

会有相同的签名

代码语言:javascript
复制
return-type func-name (data-type 2 , data-type-1);

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

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-07-07 13:20:37

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

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

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

test.cpp

代码语言:javascript
复制
int f(int x) {}

int f(double x, char y) {}

使用

代码语言:javascript
复制
g++ -S test.cpp

这就产生了汇编语言文件(略有删节):

test.s

代码语言:javascript
复制
.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)。请注意,参数的顺序也是编码的!

现在想一想,如果你有

代码语言:javascript
复制
int f(int x) {}
int f(int y) {}

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

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

票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11372476

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档