c++ - 关于 C++ 中名称修饰的问题

标签 c++ c compilation linker name-mangling

我正在尝试学习和理解 C++ 中的名称修饰。以下是一些问题:

(1) 来自 devx

When a global function is overloaded, the generated mangled name for each overloaded version is unique. Name mangling is also applied to variables. Thus, a local variable and a global variable with the same user-given name still get distinct mangled names.

除了重载函数和同名全局和局部变量之外,还有其他使用名称修饰的示例吗?

(2) 来自 Wiki

The need arises where the language allows different entities to be named with the same identifier as long as they occupy a different namespace (where a namespace is typically defined by a module, class, or explicit namespace directive).

我不太明白为什么名称修饰只适用于标识符属于不同命名空间的情况,因为重载函数可以在同一个命名空间中,并且同名全局变量和局部变量也可以在同一个空间中.这个怎么理解?

同名但在不同范围内的变量是否也使用名称修饰?

(3) C 有名称修饰吗?如果不是,那如何处理一些全局变量和局部变量同名的情况呢? C 没有重载函数,对吧?

感谢和问候!

最佳答案

C 不进行名称修饰,尽管它确实在函数名称前附加下划线,因此 printf(3) 实际上是 libc 对象中的 _printf

在 C++ 中,情况有所不同。它的历史是最初 Stroustrup 创建了“C with classes”或cfront。 ,一个将早期的 C++ 转换为 C 的编译器。然后我们将使用其他工具 - C 编译器和链接器来生成目标代码。这意味着必须以某种方式将 C++ 名称转换为 C 名称。这正是name mangling做。它为每个类成员和全局/命名空间函数和变量提供一个唯一的名称,因此命名空间和类名(用于解析)和参数类型(用于重载)以某种方式包含在最终的链接器名称中。

使用 nm(1) 等工具很容易看到这一点- 编译您的 C++ 源代码并查看生成的符号。以下是在 OSX 上使用 GCC:

namespace zoom
{
    void boom( const std::string& s )
    {
        throw std::runtime_error( s );
    }
}

~$ nm a.out | grep boom
0000000100001873 T __ZN4zoom4boomERKSs

在 C 和 C++ 中,本地(自动)变量不产生符号,而是存在于寄存器或堆栈中。

编辑:

局部变量在生成的目标文件中没有名称,仅仅是因为链接器不需要知道它们。所以没有名字,没有修改。其他所有内容(链接器必须查看)都在 C++ 中进行了名称修改。

关于c++ - 关于 C++ 中名称修饰的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2937273/

相关文章:

c - 关于将 CLI 解析器链接到我的应用程序

c - 为什么将 main 声明为数组编译?

java - 从 jar 文件创建 .class 文件 -java

c++ - C++11 的用户自定义字面量(扩展字面量)……哪些编译器支持?

c++ - 在 C++ 中继承私有(private)成员

c++ - 文件输入输出。无法使用文件路径

c - 没有得到除法和模数的输出

Javac 找不到用于 apache 公共(public)配置的 jar

swift - Lambda/闭包大小导致编译超时

c++ - 使用精神以替代方式解析结构时混淆输出