关于C+中名称损坏的问题+; 我试图学习和理解C++中的名字修改。以下是一些问题:

关于C+中名称损坏的问题+; 我试图学习和理解C++中的名字修改。以下是一些问题:,c++,c,compilation,linker,name-mangling,C++,C,Compilation,Linker,Name Mangling,(1) 从 重载全局函数时,为每个重载版本生成的损坏名称是唯一的。名称混乱也适用于变量。因此,具有相同用户名的局部变量和全局变量仍然会得到不同的损坏名称 除了重载函数和同名全局和局部变量之外,还有其他使用名称混乱的示例吗 (2) 从 当语言允许不同的实体使用相同的标识符命名,只要它们占用不同的名称空间(其中名称空间通常由模块、类或显式名称空间指令定义)时,就需要这样做 我不太明白为什么名称篡改只适用于标识符属于不同名称空间的情况,因为重载函数可以在同一名称空间中,相同名称的全局和局部变量也可以在

(1) 从

重载全局函数时,为每个重载版本生成的损坏名称是唯一的。名称混乱也适用于变量。因此,具有相同用户名的局部变量和全局变量仍然会得到不同的损坏名称

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

(2) 从

当语言允许不同的实体使用相同的标识符命名,只要它们占用不同的名称空间(其中名称空间通常由模块、类或显式名称空间指令定义)时,就需要这样做

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

名称相同但作用域不同的变量是否也使用名称混乱

(3) C有名称mangling吗?如果没有,它如何处理某些全局变量和局部变量具有相同名称的情况?C没有重载函数,对吗

谢谢和问候

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

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


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

从技术上讲,它是“装饰”。这听起来不那么粗糙,但也有点混乱,这意味着
CreditInterest
可能会被重新排列成
IntCrederestit
,而实际发生的情况更像
_CreditInterest@4
公平地说,这是“装饰”多于破损。也就是说,我也叫它mangling:-)但是如果你搜索“C++名称修饰”,你会发现更多的技术信息和例子。

C不进行名称损坏,尽管它会在函数名前加下划线,所以
printf(3)
实际上是libc对象中的
\printf

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

<>这是很容易看到的工具,比如编译你的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++中的名称。

< P><强> Muffle只是编译器如何保持链接器的快乐。

在C语言中,无论发生什么情况,都不能有两个同名函数。这就是链接器编写的目的:唯一的名称。(您可以在不同的编译单元中使用静态函数,因为链接器对它们的名称不感兴趣。)

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

具体的破坏方式对程序员来说并不重要,只对编译器重要,事实上,每个编译器的破坏方式都是不同的。重要的是,对于链接器来说,具有相同基名称的每个函数都是唯一的

现在您可以看到,将名称空间和模板添加到混合中会不断扩展该原则。

来源:

名称Mangle是C++编译器使用的过程,它为程序中的每个函数提供唯一的名称。在C++中,程序通常至少有几个函数,名称相同。因此,名称的模糊可以被看作是C++中的一个重要方面。 示例: 通常,成员名称是通过将成员名称与类名称连接在一起而唯一生成的,例如,给定声明:

class Class1
 {
        public:
            int val;
            ...
  };
val变得像:

  // a possible member name mangling
 val__11Class1
有更多关于什么是名称损坏以及如何在不同编译器中进行的信息

名称MangLink(也称为NoNo饰)是C++的一种方法 编译器向函数名和 对象文件中的对象。链接器在 一个模块中定义的函数或对象是从另一个模块引用的 模块。名称mangling用于以下目的:

  • 使链接器能够区分重载函数的不同版本
  • 使链接器能够检查对象和函数在所有模块中的声明方式是否完全相同
  • 使链接器能够在错误消息中提供有关未解析引用类型的完整信息
  • 名称mangling的发明是为了实现目的1。其他目的 并非所有编译器都完全支持这些辅助功能。这个 必须为函数提供的最小信息是名称 函数及其所有参数的类型