为什么g ++不生成"原始"符号?

Ult*_*awk 7 c++ name-mangling

从C我们知道什么是合法变量名称.法律名称的一般正则表达式类似于[\w_](\w\d_)*.

使用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;}
}
Run Code Online (Sandbox Code Playgroud)

不编译

int ::test::A::myFunction(const int a)\0
Run Code Online (Sandbox Code Playgroud)

相反,它被编译为 - 在我的64位机器上,使用g ++ 4.9.2 -

0000000000000000 T _ZN4test1A10myFunctionEi
Run Code Online (Sandbox Code Playgroud)

此输出由读取nm.代码是使用编译的g++ -c test.cpp -o out

Mar*_*k B 5

我确信这个决定是务实的,以避免对预先存在的C连接器进行任何更改(很可能甚至来自cfront).通过使用相同的字符集发出符号,使用C链接器,您不必进行任何数量的更新,并且可以使用现成的链接器.

此外,C和C++是广泛的可移植语言,他们不希望冒险通过包含意外符号来破坏更加模糊的二进制格式(可能在嵌入式系统上).

最后因为你总是可以解码(gc++filt例如类似的东西),所以使用全文表示似乎不值得.

PS您绝对不希望在函数名称中包含参数名称:如果重命名参数会破坏ABI,人们将不会感到高兴.已经很难保持ABI兼容性了.


iva*_*eev 1

  1. 由于链接器(包括操作系统的动态链接器)对导出名称施加的限制 - 字符集、长度。损坏现象正是因此而产生的。
    • 推论:在不存在这些限制的介质中(使用自己的链接器的各种虚拟机:例如.NET、Java),重整也不存在。
  2. 每个生成与其他编译器不兼容的导出的编译器必须使用不同的方案。因为链接器(静态或动态)不关心 ABI,它只关心标识符。