我们知道在C++中有函数重载这样一个东西,当我们定义了几个功能类似且函数名是一样的函数的时候,只要它的参数列表不同,编译是可以通过的,但是在C中是不可以的。

double add(double a, double b)
{return a + b;
}int add(int a, char b)
{return a + b;
}
char add(char a, char b)
{return a + b;
}

如果这样写的代码,在C中会报出errorC2371,说是add函数重定义。但是如果在C++环境下这样是允许的,叫做函数的重载,只要你的几个函数符合函数重载的要求,是完全没有问题的。这就引出了在C和C++中函数名的修饰规则,为什么在C 中就是不行的?

double add(double a, double b);
//{
// return a + b;
//}

我把这个函数的定义改为声明,然后在main函数中调用,就可以看到提示中的

1. C编译器的函数名修饰规则 

编译器给我们报出了一个链接错误,可以看到_add这样的函数,这就是在C环境下编译器对我们函数名的修饰,可以看到是在函数的前面加上下划线,当然这种修改实在默认调用约定__cdecl的情况下,如果在__stdcall调用约定,编译器和链接器会在输出函数名前加上一个下划线前缀,函数名后面加上一个“@”符号和其参数的字节数,__fastcall调用约定在输出函数名前加上一个“@”符号,后面也是一个“@”符号和其参数的字节数。

我们可以修改一下调用约定,看看是不是这样的。

这样修改之后再看看,可以看到add函数被修饰为_add@16.所以在不同调用约定下修饰规则也是有所不同的。

1. C++编译器的函数名修饰规则 

然后,再看看在C++环境下,编译器对我们的函数是怎样修饰的:

可以看到,对于我声明的double add(double a,double b)函数,被修饰为 (?add@@YANNN@Z),可以看到,这和在C环境中是完全不一样的,所以这也是在C++中有函数重载的原因,那么来看看这到底是怎么修饰的。

C++的函数名修饰规则有些复杂,但是信息更充分,通过分析修饰名不仅能够知道函数的调用方式,返回值类型,参数个数甚至参数类型。不管__cdecl,__fastcall还是__stdcall调用方式,函数修饰都是以一个“?”开始,后面紧跟函数的名字,再后面是参数表的开始标识和按照参数类型代号拼出的参数表。对于__stdcall方式,参数表的开始标识是“@@YG”,对于__cdecl方式则是“@@YA”,对于__fastcall方式则是“@@YI”。参数表的拼写代号如下所示: 
X--void    
D--char    
E--unsigned char    
F--short    
H--int    
I--unsigned int    
J--long    
K--unsigned long(DWORD) 
M--float    
N--double    
_N--bool 
U--struct

可以看到N是代表double类型,那么 (?add@@YANNN@Z)就能理解了,函数修饰符?,接着是函数名字,然后是_cdecl约定的开始标示符@@YA然后连着的是返回值类型,参数列表的参数类型刚好是,那么double add(double a,double b)就是NNN,参数表后以“@Z”标识整个名字的结束,如果该函数无参数,则以“Z”标识结束。

还有当参数列表有指针的时候,指针的方式有些特别,用PA表示指针,用PB表示const类型的指针。后面的代号表明指针类型,如果相同类型的指针连续出现,以“0”代替,一个“0”代表一次重复。

举一个简单的例子: int fun(int *p1, int *p2);

可以看到,我的fun函数被修饰为(?fun@@YAHPAH0@Z)。

还有在C++中的成员函数中公有和私有的成员函数的修饰也有相应的表示符。总而言之,在C++环境中的函数名修饰的时候,会带有参数列表的信息,还有返回值的信息,所以在C++中的函数重载就是允许存在的,因为它可以根据你的参数列表选择对应的函数,而显然在我们的C环境下是不允许的。

转载于:https://www.cnblogs.com/MrListening/p/5514610.html

C++编译器的函数名修饰规则相关推荐

  1. Linux函数名加数字,C++ 编译器的函数名修饰规则

    函数名字修饰(Decorated Name)方式 函数的名字修饰(Decorated Name)就是编译器在编译期间创建的一个字符串,用来指明函数的定义或原型.LINK程序或其他工具有时需要指定函数的 ...

  2. C/C++函数名修饰约定

    函数名字修饰(Decorated Name)方式 函数的名字修饰(Decorated Name)就是编译器在编译期间创建的一个字符串,用来指明函数的定义或原型. 正在装载数据-- LINK程序或其他工 ...

  3. 函数调用约定 and 函数名字修饰规则

    使用C/C++语言开发软件的程序员经常碰到这样的问题:有时候是程序编译没有问题,但是链接的时候总是报告函数不存在(经典的LNK2001错误),有时候是程序编译和链接都没有错误,但是只要调用库中的函数就 ...

  4. C/C++函数名称修饰规则及extern C的作用(函数名压扎)

    一.函数名称修饰规则 函数的名字修饰(Decorated Name)就是编译器在编译期间创建的一个字符串,用来指明函数的定义或原型.LINK程序或其他工具有时需要指定函数的名字修饰来定位函数的正确位置 ...

  5. C++函数名的修饰规则

    我们知道在C++中有函数重载这样一个东西,当我们定义了几个功能类似且函数名是一样的函数的时候,只要它的参数列表不同,编译是可以通过的,但是在C中是不可以的. double add(double a, ...

  6. c, c++函数名编译符号修饰符说明

    C++ 编译器的函数名修饰规则 函数名字修饰(Decorated Name)方式 函数的名字修饰(Decorated Name)就是编译器在编译期间创建的一个字符串.用来指明函数的定义或原型. LIN ...

  7. [转][C/C++]函数名字修饰(Decorated Name)方式

    1.C/C++函数修饰名: 对于我们的C/C++源程序而言,函数名只是函数的一小部分,函数还有调用方式(参数入栈方式).返回值类型.参数个数和各参数类型等信息,对于C++类成员函数,还有更多信息.这些 ...

  8. 函数的调用规则(__cdecl,__stdcall,__fastcall,__pascal)

    关于函数的调用规则(调用约定),大多数时候是不需要了解的,但是如果需要跨语言的编程,比如VC写的dll要delphi调用,则需要了解. microsoft的vc默认的是__cdecl方式,而windo ...

  9. C++ 动态库导出函数名“乱码”及解决

    刚接触C++,在尝试从 dll 中导出函数时,发现导出的函数名都"乱码"了. 导出过程如下: 新建一个Win32项目: 新建的解决方案里有几个导出的示例: // 下列 ifdef ...

  10. C++ 编写的DLL导出的函数名乱码含义解析

    C++编译时函数名修饰约定规则: __stdcall调用约定:   1.以"?"标识函数名的开始,后跟函数名:      2.函数名后面以"@@YG"标识参数表 ...

最新文章

  1. Android 依赖库发布(上传 Library 到 JCenter)gradle最高支持4.4
  2. LuManager 高危SQL注入0day分析
  3. linux复盘:构架搭建lamp(安装)
  4. Spring 一二事(8) - annotation 形式的 MVC
  5. Math.Celing、Math.Floor、Math.DivRem与Math.BigMul
  6. mySPA set delivery mode 之后,Chrome network 里观察不到cart 请求了
  7. SpringBoot (6)---RestTemplate方法详解(2)
  8. 获取指定路径下所有PDF文件的总页数
  9. php启动另一个php进程,用php守护另一个php进程的例子
  10. 微信小程序使用字体图标库
  11. 太阳影子定位问题研究
  12. linux 图形设计软件,Ubuntu下使用Blender 3D图形专业设计工具
  13. android手机脱网分析,网络营销-13款手机浏览器分析(Android).pptx
  14. [C#复习向整合]反射 -Assembly与Activator
  15. unity的切屏显示顺序
  16. SAS学习(8)——自定义proc means的数据导出
  17. 微信小程序入门实例--地图
  18. 3dsmax2021图文安装教程
  19. 计算机常用英语对话,英语口语对话之买电脑时常用基本口语
  20. php 判断是否汉字

热门文章

  1. 建武28a对讲机最大距离_小米对讲机再出新品:不但价格低,还能一键写频
  2. Caffe学习:使用pycaffe生成mean_file.py文件
  3. 阿里云服务器Centos7 安装 pycuda报错:Could not build wheels for pycuda which use PEP 517 and cannot be install
  4. python模块之scipy的层次聚类简单测试与使用
  5. Linux网络编程和套接字
  6. C++ queue队列如何遍历
  7. kubernetes 查看日志方法
  8. C语言怎样将一个字符串逆序,C语言,求一个字符串的逆序
  9. sdk 今日头条_Unity接入今日头条广告(激励广告)
  10. 微信小程序支付封装-复制即用