为什么 g++ 不生成"raw"符号?
Why doesn't g++ generate "raw" symbols?
从C中我们知道什么是合法的变量名。合法名称的通用正则表达式看起来类似于[w_](wd_)*
。
使用dlsym
,我们可以加载任意字符串,并且c++在ABI中修改包含@的名称…
我的问题是:可以使用任意字符串吗?关于dlsym的文档似乎没有提到任何东西。
出现的另一个问题似乎意味着完全有可能有任意以null结尾的符号。这促使我提出以下问题:
为什么g++不发出带有名称和参数列表的原始函数签名,包括名称空间和类成员?
我的意思是:
namespace test {
class A
{
int myFunction(const int a);
};
}
namespace test {
int A::myFunction(const int a){return a * 2;}
}
不被编译为
int ::test::A::myFunction(const int a)
相反,它在我的64位机器上被编译为-,使用g++ 4.9.2 -
0000000000000000 T _ZN4test1A10myFunctionEi
该输出由nm
读取。代码使用g++ -c test.cpp -o out
我确信这个决定是务实地做出的,以避免对已有的C链接器(很可能甚至起源于cfront)进行任何更改。通过使用与C链接器相同的字符集发出符号,您不需要进行任何数量的更新,并且可以使用现成的链接器。
此外,C和c++是广泛可移植的语言,它们不希望冒险通过包含意外的符号来破坏更模糊的二进制格式(可能在嵌入式系统上)。
最后,由于您总是可以要求(例如gc++filt
),因此使用全文表示似乎不值得。
注:您绝对不希望在函数名中包含参数名:如果重命名参数破坏了ABI,人们将不高兴。保持ABI兼容性已经够难的了。
GCC兼容Itanium c++ ABI。如果您的问题是"为什么Itanium c++ ABI要求以这种方式篡改名称?",那么答案很可能是
- 因为它的设计者认为这是个好主意 符号越短,对象文件越小,动态链接越快。
- 由于链接器(包括操作系统的动态链接器)对导出名称施加的限制-字符集,长度。正是由于这个原因,才出现了破损的现象。
- 推论:在这些限制不存在的媒体中(各种使用自己的链接器的vm:例如。net, Java), mangling也不存在。
- 每个编译器产生的导出与其他编译器不兼容,必须使用不同的模式。因为link(静态或动态)不关心abi,它只关心标识符。
你基本上回答了你自己的问题:
合法名称的通用正则表达式看起来类似于
[w_](wd_)*
。
从一开始,c++就使用了预先存在的(C)链接器/加载器技术。ld
, ld-linux.so
等都没有"c++"。
所以链接仅限于C语言中已经合法的内容。它不包括冒号、括号、与号、星号和其他任何您需要在纯文本中编码c++标识符的东西。
(在这个答案中,我忽略了您在::test::A::void myFunction(const int a)
的示例中犯了几个错字)
格式为:
- 不是programmer-specific;考虑到所有这些都是相同的,所以为什么要混淆人们:
-
int ::test::A::myFunction(const int)
-
int ::test::A::myFunction(int const)
-
int test::A::myFunction(int const)
-
int test :: A :: myFunction (int const)
- 等等& help;
-
- 明确
- 简洁;没有参数名称或其他不必要的装饰
- 更容易解析(注意每个组件的长度都以数字形式呈现)
同时,我认为为c++ ABI选择一种类似于c++的人类可读格式没有任何好处。这东西应该是为机器优化的。为什么你要让它对机器不那么理想,而让它对人类更理想呢?而且很可能在做后者的时候失败了。
你说你的编译器不发出"原始符号"。
- 在C++中,将大的无符号浮点数四舍五入为整数的最佳方法是什么
- 有符号的int和int-有没有一种方法可以在C++中区分它们
- 将无符号char*转换为std::istream*C++
- 如何在C++中将一个无符号的 int 转换为两个无符号的短裤?
- vscode g++链路故障:体系结构x86_64的未定义符号
- 从矢量<无符号字符>转换为字符* 包括垃圾数据
- 如何理解将半精度指针转换为无符号长指针和相关的内存对齐
- Visual studio代码重构似乎不起作用(例如,重命名符号-f2)
- 使用gcc从静态链接的文件中查找可选符号
- C++中无符号字符溢出
- 使用无符号字符数组有效存储内存
- C++:Application.cpp中抛出了未解析的外部符号(解决方案在问题的末尾,供未来的读者参考)
- VC++本机单元测试,找不到调试符号
- 为什么我必须在C++中添加一个赋值符号来声明一个数组
- 检查TCHAR数组输入是否为带符号整数C++
- 用符号版本替换对函数的所有调用
- 未解析的外部符号_MsiLocateComponentW@12.
- 如何打印boost多精度128位无符号整数
- C++模板函数,用于比较任何无符号整数和有符号整数
- 为什么 g++ 不生成"raw"符号?