问题描述
我要求理解这一点,在c语言中没有名称修饰,但c ++具有。例如,这是如何工作的,说我有以下文件
文件exlib.hpp
#ifndef EXLIB
#define EXLIB
#include <iostream>
int sum(int,int);
int sum(int,int,int);
#endif
文件exlib.cpp
#include "exlib.hpp"
int sum(int a,int b)
{
std::cout << "In sum(int,int)" << std::endl;
return a + b;
}
int sum(int a,int b,int c)
{
std::cout << "In sum(int,int)" << std::endl;
return a + b + c;
}
int sum(int a,int c,int d)
{
std::cout << "In sum(int,int)" << std::endl;
return a + b + c + d;
}
文件exapp.cpp
#include "iostream"
#include "exlib.hpp"
int main()
{
std::cout << "Sum = " << sum(1,1) << std::endl;
std::cout << "Sum = " << sum(2,2,2) << std::endl;
std::cout << "Sum = " << sum(3,3,3) << std::endl;
}
编译
$ g++ -c exlib.cpp
$ g++ exapp.cpp exlib.o -o exapp
$ ./exapp
exlib.o中的sum是错误的名字吗?
输出:
Sum = In sum(int,int)
2
Sum = In sum(int,int)
6
Sum = In sum(int,int)
12
谢谢。
解决方法
尽管C ++提供了Polymorphism(即,通过使用其他功能来区分它们,可以在同一范围内将不同的事物命名为相等),但链接程序不支持此功能(静态链接或动态链接均不支持)。因此,C ++编译器使用name mangling。 (其他功能用于装饰原始标识符以产生唯一的名称。)
C ++编译器自行编译每个C ++文件(也称为translation unit)。因此,很明显,此编译器必须以唯一,可复制的方式完成名称处理。即相同的声明必须始终映射到相同的符号。 否则,链接器将不可能解析在一个文件中声明(仅)在另一个文件中定义的符号。
但是,没有通用的名称处理标准(例如,作为C ++标准的一部分)。
因此,即使在同一平台上,由于不同的名称处理(以及其他详细信息),由两个不同的编译器生成的二进制代码也可能不兼容。 (对于MS Visual C++,这甚至使来自不同版本的二进制文件也不兼容。)
为克服此问题,某些平台(例如Linux)存在Application Binary Interfaces(ABI)。 ABI的一个细节是标准化的名称处理。