博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
名称的特殊处理(Name Mangling)
阅读量:7284 次
发布时间:2019-06-30

本文共 1394 字,大约阅读时间需要 4 分钟。

先说一个事情, mangle 的意思是 vt.乱砍, 损坏; n. 碾压机。 这意味着 name mangling 就是要先把你精心想出的名字们碾碎, 再拼成独一无二的样子, 当然这么残忍的事情都是编译器瞒着你做的。

一般而言, member 的名称前会被加上 class 名称, 形成独一无二的命名, 例如:

class Bar(){
public: int ival;};//其中的 ival 可能变成这样://member 经过 name-mangling 后的结果之一ival__3Bar

编译器你为何要这样? 请考虑这样的派生操作:

class Foo: public Bar{
public: int ival;};//所以必须 name-mangling 为:class Foo{public: int ival__3Bar; int ival__3Foo;};

而对于函数, 因为 member function 可以被重载化, 所以需要更广泛的 magling 手法(更残酷的碾碎, 嗯嗯), 如:

class Point{public:    void (float newX);    float x();    ...};//转化为class Point{public:    //这样能行?    void x__5Point(float newX);    float x__5Point();    ...};

函数如果这么转化, 会导致被重载化的函数实体拥有相同的名称, 为了让它们独一无二, 唯有再加上它们的参数链表(可以从参数原型得到)。 如果把参数类型也编码进去, 就一定可以制造出独一无二的效果, 使我们的 x() 函数有良好的转换(但如果你声明 extern "C" , 就会压抑 nonmember functions的 mangling 效果):

class Point{public:    void x__5PointFf(float newX);    float x__5PointFv();    ...};

以上所示的只是 cfront 的编码方法, 目前的编译器并没有统一的编码方法。

把参数和函数名称编码在一起, 编译器于是在不同的编译模块之间达成了一种有限的类型检验。 如:

void print(const Point3d&){}

但意外的被这样声明和调用:

void print(const Point3d&);

两个实体如果拥有独一无二的 name-mangling, 那么任何不不正确的调用操作在链接时期就因无法决议而失败。有时候我们把它称为 “确保类型安全的链接行为”。 我觉得这样很乐观, 因为它只可以捕捉函数的标记(或叫做函数签名, 就是指 函数名称 + 参数数目 + 参数类型)错误: 如果 “返回类型” 声明错误, 就没办法检查出来!
在当前的编译系统中, 有一种所谓的 demangling 工具, 用来拦截名称并将其转换回去, 使用者仍然可以处于 “不知道类型名字的极大幸福之中”。
因为 name-mangling 的手法残忍, 结果不堪, 所以一般不会给使用者看到。

转载于:https://www.cnblogs.com/wuOverflow/p/4115592.html

你可能感兴趣的文章
python 操作 K8S
查看>>
「docker实战篇」python的docker-抖音appium模拟滑动操作(22)
查看>>
C语言中什么是原型定义
查看>>
Mail服务器架设
查看>>
C++中关于指针作为参数传递的问题
查看>>
大清单报表应当怎么做?
查看>>
Spring AOP 实现方法日志记录以及执行时间打印
查看>>
Linux中 tail -f;tail -F;tailf的区别
查看>>
Linux下的数据备份工具rsync
查看>>
支付宝小程序注意事项
查看>>
ArrayList
查看>>
【小松教你手游开发】【unity实用技能】List列表排序
查看>>
日常工作之Zabbix源码编译,兼容mysql5.6
查看>>
Zabbix分布式监控
查看>>
中兴智能视觉大数据报道:人工智能相当火爆,或将下一个风口
查看>>
OCP 12c最新考试原题及答案(071-3)
查看>>
xdebug+phpstorm(windows)
查看>>
Spring Boot整合Hibernate操作
查看>>
阿里云移动端播放器高级功能---直播时移
查看>>
主动式部署陷阱
查看>>