关于 C++ 中名称修改的问题
我正在尝试学习和理解 C++ 中的名称修饰。以下是一些问题:
(1)来自 devx
当全局函数被重载时,为每个重载版本生成的重整名称是唯一的。名称修饰也适用于变量。因此,具有相同用户给定名称的局部变量和全局变量仍然会获得不同的损坏名称。
除了重载函数和同名全局变量和局部变量之外,还有其他使用名称修饰的示例吗?
(2) 来自 Wiki
当语言允许不同的实体使用相同的标识符命名时,只要它们占据不同的命名空间(其中命名空间通常由模块、类或显式命名空间指令定义),就会出现这种需求。
我不太明白为什么名称修饰仅适用于标识符属于不同命名空间的情况,因为重载函数可以位于同一命名空间中,并且同名全局变量和局部变量也可以位于同一空间中。这怎么理解呢?
名称相同但作用域不同的变量是否也使用名称修饰?
(3) C 有名称修改吗?如果不是,那么如何处理某些全局变量和局部变量同名的情况呢? C 没有重载函数,对吗?
谢谢和问候!
I am trying to learn and understand name mangling in C++. Here are some questions:
(1) From 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
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?
Thanks and regards!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
C 不会进行名称修改,但它会在函数名称前添加下划线,因此
printf(3)
实际上是 libc 对象中的_printf
。在 C++ 中,情况有所不同。它的历史是,最初 Stroustrup 创建了“带有类的 C”或 cfront,一个编译器将早期的 C++ 翻译为 C。然后我们将使用其余工具 - C 编译器和链接器来生成目标代码。这意味着 C++ 名称必须以某种方式转换为 C 名称。这正是名称修改所做的。它为每个类成员以及全局/命名空间函数和变量提供唯一的名称,因此命名空间和类名称(用于解析)以及参数类型(用于重载)以某种方式包含在最终的链接器名称中。
使用
nm(1)
- 编译您的 C++ 源代码并查看生成的符号。以下是在带有 GCC 的 OSX 上的情况:在 C 和 C++ 中,局部(自动)变量不产生符号,而是存在于寄存器或堆栈中。
编辑:
局部变量在生成的目标文件中没有名称,仅仅是因为链接器不需要知道它们。所以没有名字,没有损坏。其他所有内容(链接器必须查看)在 C++ 中都是名称损坏的。
C does not do name mangling, though it does pre-pend an underscore to function names, so the
printf(3)
is actually_printf
in the libc object.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 mangling does. 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.
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:In both C and C++ local (automatic) variables produce no symbols, but live in registers or on stack.
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++.
Mangling 就是编译器让链接器保持满意的方式。
在 C 中,无论如何都不能有两个同名的函数。这就是链接器的编写假设:唯一的名称。 (您可以在不同的编译单元中拥有静态函数,因为链接器不关心它们的名称。)
在 C++ 中,您可以拥有两个同名的函数,只要它们具有不同的参数类型即可。因此,C++ 以某种方式将函数名称与类型组合起来。这样链接器就会将它们视为具有不同的名称。
重整的确切方式对程序员来说并不重要,只有编译器重要,而且事实上每个编译器的做法都不同。重要的是每个具有相同基本名称的函数都以某种方式对于链接器来说是唯一的。
现在您可以看到,将命名空间和模板添加到混合中可以不断扩展该原则。
Mangling is simply how the compiler keeps the linker happy.
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.)
In C++, you can have two functions with the same name as long as they have different parameter types. So C++ combines the function name with the types in some way. That way the linker sees them as having different names.
The exact manner of mangling is not significant to the programmer, only the compiler, 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.
从技术上来说,它是“装饰”。这听起来不那么粗暴,但也暗示着
CreditInterest
可能会被重新排列成IntCrederestit
而实际发生的情况更像是_CreditInterest@4
这是公平地说,“装饰”多于损坏。也就是说,我也称其为损坏:-),但是如果您搜索“C++ 名称装饰”,您会找到更多技术信息和示例。Technically, it's "decorating". It sounds less crude but also mangling sort of implies that
CreditInterest
might get rearranged intoIntCrederestit
whereas what actually happens is more like_CreditInterest@4
which 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".除了重载函数和同名全局变量和局部变量之外,还有其他使用名称修饰的示例吗?
C++ 总是修饰所有符号。对于编译器来说更容易。通常,重整会对参数列表或类型进行编码,因为这些是需要重整的最常见原因。
C 不会损坏。作用域用于控制对同名局部变量和全局变量的访问。
Are there other examples that are using name mangling, besides overloading functions and same-name global and local variables?
C++ mangles all symbols, 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 does not mangle. Scoping is used to control access to local and global variables of the same name.
资料来源:http://sickprogrammersarea.blogspot.in/2014 /03/technical-interview-questions-on-c_6.html
名称修改是 C++ 编译器使用的过程,为程序中的每个函数提供唯一的名称。在 C++ 中,通常程序至少有几个同名的函数。因此,名称修饰可以被视为 C++ 中的一个重要方面。
示例:
通常,成员名称是通过将成员名称与类名称连接起来唯一生成的,例如给定声明:
val 变为如下所示:
Source: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++.
Example:
Commonly, member names are uniquely generated by concatenating the name of the member with that of the class e.g. given the declaration:
val becomes something like:
agner 提供了有关什么是名称修改以及如何在不同编译器中完成此操作的更多信息。
agner has more information on what is a name mangling and how it is done in different compilers.