关于 C++ 中名称修改的问题

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2937273/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 11:33:30  来源:igfitidea点击:

questions about name mangling in C++

c++ccompilationlinkername-mangling

提问by Tim

I am trying to learn and understand name mangling in C++. Here are some questions:

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

(1) From devx

(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.

当全局函数被重载时,为每个重载版本生成的重整名称是唯一的。名称修饰也适用于变量。因此,具有相同用户给定名称的局部变量和全局变量仍然获得不同的重整名称。

Are there other examples that are using name mangling, besides overloading functions and same-name global and local variables ?

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

(2) From Wiki

(2) 来自维基

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).

如果语言允许使用相同标识符命名不同实体,只要它们占据不同的命名空间(其中命名空间通常由模块、类或显式命名空间指令定义),就会出现这种需求。

I don't quite understand why name mangling is only applied to the cases when the identifiers belong to different namespaces, since overloading functions can be in the same namespace and same-name global and local variables can also be in the same space. How to understand this?

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

Do variables with same name but in different scopes also use name mangling?

名称相同但作用域不同的变量是否也使用名称修饰?

(3) Does C have name mangling? If it does not, how can it deal with the case when some global and local variables have the same name? C does not have overloading functions, right?

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

Thanks and regards!

感谢致敬!

回答by Nikolai Fetissov

C does not do name mangling, though it does pre-pend an underscore to function names, so the printf(3)is actually _printfin the libc object.

C 不进行名称修改,尽管它确实在函数名称前加了一个下划线,因此printf(3)它实际上_printf在 libc 对象中。

In C++ the story is different. The history of it is that originally Stroustrup created "C with classes" or cfront, a compiler that would translate early C++ to C. Then rest of the tools - C compiler and linker would we used to produce object code. This implied that C++ names had to be translated to C names somehow. This is exactly what name manglingdoes. It provides a unique name for each class member and global/namespace function and variable, so namespace and class names (for resolution) and argument types (for overloading) are somehow included in the final linker names.

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

This is very easy to see with tools like nm(1)- compile your C++ source and look at the generated symbols. The following is on OSX with GCC:

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

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

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

In both C and C++ local (automatic) variables produce no symbols, but live in registers or on stack.

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

Edit:

编辑:

Local variables do not have names in resulting object file for mere reason that linker does not need to know about them. So no name, no mangling. Everything else (that linker has to look at) is name-mangled in C++.

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

回答by egrunin

Mangling is simply how the compiler keeps the linker happy.

Mangling 只是编译器让链接器满意的方式。

In C, you can't have two functions with the same name, no matter what. So that's what the linker was written to assume: unique names. (You can have static functions in different compilation units, because their names aren't of interest to the linker.)

在 C 中,无论如何都不能有两个同名的函数。所以这就是链接器被编写的假设:唯一的名称。(您可以在不同的编译单元中使用静态函数,因为链接器不关心它们的名称。)

In C++, you can have two functions with the same name as long as they have different parameter types. So C++ combinesthe function name with the types in some way. That way the linker sees them as having different names.

在 C++ 中,你可以有两个同名的函数,只要它们的参数类型不同。所以C++以某种方式函数名和类型结合起来。这样链接器就会将它们视为具有不同的名称。

Note that it doesn't matter how the name gets mangled, and in fact every compiler does it differently. All that matters is that every function with the same base name is somehow made unique for the linker.

请注意,名称如何被修改并不重要,实际上每个编译器的处理方式都不一样。重要的是,每个具有相同基本名称的函数都以某种方式为链接器设置了唯一性。

You can see now that adding namespaces and templates to the mix keeps extending the principle.

您现在可以看到,将命名空间和模板添加到混合中继续扩展该原则。

回答by Kate Gregory

Technically, it's "decorating". It sounds less crude but also mangling sort of implies that CreditInterestmight get rearranged into IntCrederestitwhereas what actually happens is more like _CreditInterest@4which is, fair to say, "decorated" more than mangled. That said, I call it mangling too :-) but you'll find more technical info and examples if you search for "C++ name decoration".

从技术上讲,它是“装饰”。这听起来不那么粗糙,但也暗示CreditInterest可能会被重新安排,IntCrederestit而实际发生的事情更像_CreditInterest@4是,公平地说,“装饰”而不是被破坏。也就是说,我也称其为 mangling :-) 但如果您搜索“C++ 名称装饰”,您会找到更多技术信息和示例。

回答by Donnie

Are there other examples that are using name mangling, besides overloading functions and same-name global and local variables?

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

C++ mangles allsymbols, always. It's just easier for the compiler. Typically the mangling encodes something about the parameter list or types as these are the most common causes of mangling being needed.

C++总是处理所有符号。这对编译器来说更容易。通常,重整对参数列表或类型进行编码,因为这些是需要重整的最常见原因。

C does not mangle. Scoping is used to control access to local and global variables of the same name.

C 不会损坏。作用域用于控制对同名局部和全局变量的访问。

回答by Santosh

Source:http://sickprogrammersarea.blogspot.in/2014/03/technical-interview-questions-on-c_6.html

来源:http: //sickprogrammersarea.blogspot.in/2014/03/technical-interview-questions-on-c_6.html

Name mangling is the process used by C++ compilers give each function in your program a unique name. In C++, generally programs have at-least a few functions with the same name. Thus name mangling can be considered as an important aspect in C++.

名称修改是 C++ 编译器使用的过程,为程序中的每个函数指定一个唯一的名称。在 C++ 中,通常程序至少有几个同名的函数。因此,名称修饰可以被视为 C++ 中的一个重要方面。

Example:Commonly, member names are uniquely generated by concatenating the name of the member with that of the class e.g. given the declaration:

示例:通常,成员名称是通过将成员名称与类名称连接起来而唯一生成的,例如给定声明:

class Class1
 {
        public:
            int val;
            ...
  };

val becomes something like:

val 变成了这样:

  // a possible member name mangling
 val__11Class1

回答by cpp_enthusiast

agnerhas more information on what is a name mangling and how it is done in different compilers.

agner有更多关于什么是名称修改以及如何在不同编译器中完成的信息。

Name mangling (also called name decoration) is a method used by C++ compilers to add additional information to the names of functions and objects in object files. This information is used by linkers when a function or object defined in one module is referenced from another module. Name mangling serves the following purposes:

  1. Make it possible for linkers to distinguish between different versions of overloaded functions.
  2. Make it possible for linkers to check that objects and functions are declared in exactly the same way in all modules.
  3. Make it possible for linkers to give complete information about the type of unresolved references in error messages.

Name mangling was invented to fulfill purpose 1. The other purposes are secondary benefits not fully supported by all compilers. The minimum information that must be supplied for a function is the name of the function and the types of all its parameters as well as any class or namespace qualifiers. Possible additional information includes the return type, calling convention, etc. All this information is coded into a single ASCII text string which looks cryptic to the human observer. The linker does not have to know what this code means in order to fulfill purpose 1 and 2. It only needs to check if strings are identical.

名称修饰(也称为名称修饰)是 C++ 编译器用来向目标文件中的函数和对象名称添加附加信息的一种方法。当一个模块中定义的函数或对象被另一个模块引用时,链接器会使用此信息。名称修改有以下目的:

  1. 使链接器可以区分不同版本的重载函数。
  2. 使链接器可以检查对象和函数在所有模块中是否以完全相同的方式声明。
  3. 使链接器能够在错误消息中提供有关未解析引用类型的完整信息。

名称修改的发明是为了实现目的 1。其他目的是并非所有编译器都完全支持的次要好处。必须为函数提供的最少信息是函数的名称及其所有参数的类型以及任何类或命名空间限定符。可能的附加信息包括返回类型、调用约定等。所有这些信息都被编码成单个 ASCII 文本字符串,这对人类观察者来说是神秘的。为了实现目的 1 和 2,链接器不必知道这段代码的含义。它只需要检查字符串是否相同。