请解释一下什么是名字改编,它是如何工作的,它解决了什么问题,并在其中的背景和语言被使用。 名称重整战略的一个加号(如什么名字是由编译器,以及为什么选择)。
Answer 1:
在您选择的编程语言,如果一个标识符是从单独编译单元出口,它需要通过其所在链接时已知的名称。 名称重整解决了编程语言超载标识符的问题 。 (标识符为“过载”,如果相同的名称是在多于一个的上下文或与多于一个的含义。)
一些例子:
在C ++中,函数或方法
get
可以在多种类型的过载。在阿达或MODULA-3,函数
get
可能出现在多个模块。
多种类型和多种模块涵盖了常用的上下文。
典型策略:
每种类型映射到串并使用组合的高级标识符和“类型字符串”作为链接时命名。 常见于C ++(因为超载特别容易只允许用于功能/方法,并且只在参数类型)和Ada(可过载的结果类型以及)。
如果一个标识符在多于一个模块或命名空间中使用,加入了模块的名称与标识符的名称,例如,
List_get
代替List.get
。
根据哪些字符是在链接时的名字法律,你可能需要做更多的忙玲; 例如,它可能有必要使用下划线作为“逃离”字符,所以可以区分
-
List_my.get
- >List__my_get
从
-
List.my_get
- >List_my__get
(诚然,这例子是达到了,但作为一个编译器作者,我必须保证源代码的地图,不同的链接时的名字是不同的标识符 。这就是全部的原因和目的的名字改编。)
Answer 2:
简单地说,名称重整是由编译器改变标识符在源代码中的名称,以帮助一个过程链接在这些标识符之间的多义性。
维基百科对这一主题的精彩的文章有几个很好的例子。
Answer 3:
名称重整是由编译器修改对象的“编译”的名字,使它比你以一致的方式指定什么不同的手段。
这允许编程语言的灵活性,提供相同的名字多次,编译对象,并有一个一致的方法来查找适当的对象。 例如,这允许多个类具有相同名称的不同的命名空间存在(通常通过预先命名空间进入类名等)。
运营商和方法重载在许多语言中,这进一步退一步 - 每种方法,以允许在一个类型的多个方法具有相同的名称存在结束了一个“错位”的名字在编译库。
Answer 4:
在蟒蛇,名称重整是由类变量有内部和外部类不同名的系统。 程序员通过把两个下划线在变量名的开头“激活”它。
例如,我可以定义一些成员的简单类:
>>> class Foo(object):
... def __init__(self):
... self.x = 3
... self._y = 4
... self.__z = 5
...
在蟒蛇的做法,开始用下划线变量名是“内部”,而不是类接口的一部分,因此程序员不应该依赖于它。 然而,它仍然是可见的:
>>> f = Foo()
>>> f.x
3
>>> f._y
4
首先是两个下划线的变量名还是公共的,但它的名字,错位,从而更难获得:
>>> f.__z
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'Foo' object has no attribute '__z'
如果我们知道如何在名称重整工作,但是,我们可以得到它:
>>> f._Foo__z
5
即类名的前面加上变量名与一个额外的下划线。
Python有没有“私人”与“公众”成员的概念; 一切都是公开的。 名称 - 重整是一个程序员可以发送变量不应从类外部访问最强的,可能的信号。
Answer 5:
来源: http://sickprogrammersarea.blogspot.in/2014/03/technical-interview-questions-on-c_6.html
名称重整是由C ++编译器用于给你的程序的唯一名称每个功能的过程。 在C ++中,一般程序具有相同名称在-至少有几个功能。 因此名称重整可被认为是在C ++的一个重要方面。
例如:通常,会员名称唯一地通过连接与给出的声明的类例如的部件的名称生成:
class Class1
{
public:
int val;
...
};
VAL变成是这样的:
// a possible member name mangling
val__11Class1
Answer 6:
在Fortran中,需要名字改编因为语言是不区分大小写的,这意味着富,FOO,FOO,FOO等将全部解决相同的符号,其名称必须以某种方式进行标准化。 不同的编译器实现重整不同,并与C或用不同的编译器编译的二进制对象交互时,这是一个很大的麻烦来源。 GNU G77 / G95,例如,总是添加一个尾随下划线的小写名字,除非其名字已经包含一个或多个下划线。 在这种情况下,两个下划线添加。
例如,以下例行程序
program test
end program
subroutine foo()
end subroutine
subroutine b_ar()
end subroutine
subroutine b_a_r()
end subroutine
产生如下错位符号:
0000000000400806 g F .text 0000000000000006 b_ar__
0000000000400800 g F .text 0000000000000006 foo_
000000000040080c g F .text 0000000000000006 b_a_r__
为了从C调用Fortran代码,在适当错位的例程名必须调用(显然保持到可能不同的mangling策略要真正编译器无关)。 要调用从FORTRAN C代码,一个C编写的接口必须正确出口错位的名称,并调用转发给C例程。 该接口然后可以从Fortran调用的。
Answer 7:
大多数面向对象语言提供了函数重载功能。 函数重载如果任何类具有相同的名称,但不同的参数类型及号码,然后他们说,超载多种功能。 函数重载允许您使用相同的名称为不同的功能。
方法重载函数
- 通过改变参数的数量。
- 列表项由具有不同类型的说法。
如何函数重载与名字改编实现?
C ++编译器不同的功能之间进行区分时,它产生目标码 - 它通过将约基于类型和数量的参数的参数信息来改变名字。 添加额外的信息来形成函数名的这种技术被称为名字粉碎。 C ++标准没有指定名称重整任何特定的技术,因此不同的编译器可以添加不同的信息的功能名称。 我已经运行在gcc4.8.4示例程序。
class ABC
{
public:
void fun(long a, long b) {}
void fun(float a, float b) {}
void fun(int a, float b) {}
};
int main()
{
ABC obj;
obj.fun(1l,2l);
obj.fun(1,2.3f);
obj.fun(3.2f,4.2f);
return 0;
}
这个程序有3个功能命名的乐趣不同,基于的参数和它们的类型号。 这些函数的名字是被损毁,如下图所示:
ayadav@gateway1:~$ nm ./a.out |grep fun
000000000040058c W _ZN3ABC3funEff
00000000004005a0 W _ZN3ABC3funEif
000000000040057a W _ZN3ABC3funEll
- ABC是类名的命令字符串
- 有趣的是函数名普通字符串
- FF 2浮子> F型的参数
- LL 2长> 1的typeof参数
- 如果第一个整数argument-> i和一个浮子>˚F参数
Answer 8:
在链接编辑设计时,语言,如C,FORTAN和COBOL没有的类和其他事情的命名空间,类成员。 名称重整需要支持面向对象的特性,例如那些不支持他们的链接编辑器。 该链接编辑器不支持的附加功能常常被漏诊的事实; 人们通过说名字改编由于链接编辑器需要的暗示吧。
由于有语言要求中这么多的变化,支持名字改编做什么,没有一个简单的解决方案如何支持它的链接编辑器的问题。 链接编辑器的设计与各种编译器的输出(对象模块)的工作,因此必须有一个普遍的方式来支持的名字。
Answer 9:
所有以前的答案是正确的,但这里是例如Python的观点看/推理。
定义
在类中的变量有__(即两个下划线)的前缀没有__(即两个下划线或更多)的后缀,然后它被认为是私人identfier。 Python解释器将任何私有的标识符,它轧液名称_class__identfier
Example:
MyClassName --> _myClassName
__variable --> __variable
为什么
这是必要的,因为避免可能通过重写属性导致的问题。 换句话说,为了覆盖,Python解释器必须能够建立对儿童的方法与父类的方法,并使用__(双下划线)不同的ID使Python来做到这一点。 在下面的例子中,没有__help这个代码是行不通的。
class Parent:
def __init__(self):
self.__help("will take child to school")
def help(self, activities):
print("parent",activities)
__help = help # private copy of original help() method
class Child(Parent):
def help(self, activities, days): # notice this has 3 arguments and overrides the Parent.help()
self.activities = activities
self.days = days
print ("child will do",self.activities, self.days)
# the goal was to extend and override the Parent class to list the child activities too
print ("list parent & child responsibilities")
c = Child()
c.help("laundry","Saturdays")
Answer 10:
这里的答案是真棒,所以这是刚刚从我的一点经验加成:我为了知道使用名字改编,用什么工具(GCC / VS / ...),以及如何传递到栈参数,什么调用约定我是处理,并基于该名称,因此,例如,如果看到_main
我知道这是一个Cdecl
他人相同