language agnostic - ¿Qué es el nombre de manipulación, y cómo funciona?
language-agnostic name-mangling (8)
Por favor explique qué es el cambio de nombre, cómo funciona, qué problema soluciona y en qué contextos e idiomas se usa. Estrategias de creación de nombres de nombres (por ejemplo, qué nombre es elegido por el compilador y por qué) un plus.
En Fortran, se necesita cambiar el nombre porque el lenguaje no distingue entre mayúsculas y minúsculas, lo que significa que Foo, FOO, fOo, foo etc. se resolverán con el mismo símbolo, cuyo nombre debe normalizarse de alguna manera. Diferentes compiladores implementan el proceso de forma diferente, y esto es una fuente de grandes problemas cuando se interactúa con C u objetos binarios compilados con un compilador diferente. GNU g77 / g95, por ejemplo, siempre agrega un guión bajo final al nombre en minúscula, a menos que el nombre ya contenga uno o más guiones bajos. En este caso, se agregan dos guiones bajos.
Por ejemplo, la siguiente rutina
program test
end program
subroutine foo()
end subroutine
subroutine b_ar()
end subroutine
subroutine b_a_r()
end subroutine
Produce los siguientes símbolos destrozados:
0000000000400806 g F .text 0000000000000006 b_ar__
0000000000400800 g F .text 0000000000000006 foo_
000000000040080c g F .text 0000000000000006 b_a_r__
Para llamar al código de Fortran desde C, se debe invocar el nombre de la rutina correctamente mutilado (obviamente teniendo en cuenta posibles estrategias diferentes de manipulación para que sea verdaderamente independiente del compilador). Para llamar al código C desde fortran, una interfaz escrita en C debe exportar los nombres correctamente alterados y reenviar la llamada a la rutina C. Esta interfaz puede ser llamada desde Fortran.
En el lenguaje de programación de su elección, si un identificador se exporta desde una unidad compilada por separado, necesita un nombre por el cual se lo conoce en el momento del enlace. El cambio de nombre resuelve el problema de los identificadores sobrecargados en los lenguajes de programación. (Un identificador está "sobrecargado" si el mismo nombre se usa en más de un contexto o con más de un significado).
Algunos ejemplos:
En C ++, la función o método
get
puede estar sobrecargado en varios tipos.En Ada o Modula-3, la función
get
puede aparecer en múltiples módulos.
Múltiples tipos y múltiples módulos cubren los contextos habituales.
Estrategias típicas:
Asigne cada tipo a una cadena y use el identificador combinado de alto nivel y "tipo cadena" como el nombre del tiempo de enlace. Común en C ++ (especialmente fácil ya que la sobrecarga solo está permitida para funciones / métodos y solo en tipos de argumentos) y Ada (donde también se pueden sobrecargar los tipos de resultados).
Si se utiliza un identificador en más de un módulo o espacio de nombres, una el nombre del módulo con el nombre del identificador, por ejemplo,
List_get
lugar deList.get
.
Dependiendo de qué caracteres sean legales en los nombres de tiempo de enlace, es posible que tenga que hacer un cambio adicional; por ejemplo, puede ser necesario utilizar el guión bajo como un carácter de "escape", para que pueda distinguir
-
List_my.get
->List__my_get
de
-
List.my_get
->List_my__get
(Es cierto que este ejemplo está llegando, pero como escritor de compiladores, tengo que garantizar que identificadores distintos en el código fuente se correlacionen con distintos nombres de tiempo de enlace . Esa es toda la razón y el propósito del mangle de nombres).
En el momento en que se diseñaron los editores de enlaces, idiomas como C, FORTAN y COBOL no tenían espacios de nombres, clases, miembros de clases y otras cosas más. El cambio de nombre es necesario para admitir características orientadas a objetos, como las que tienen un editor de enlaces que no las admite. El hecho de que el editor de enlaces no es compatible con las características adicionales a menudo se pierde; la gente lo insinúa diciendo que se requiere el cambio de nombre debido al editor de enlace.
Debido a que hay tanta variación entre los requisitos de lenguaje para soportar lo que hace el cambio de nombre, no hay una solución simple al problema de cómo admitirlo en un editor de enlaces. Los editores de enlaces están diseñados para funcionar con salida (módulos de objetos) de una variedad de compiladores y, por lo tanto, deben tener una forma universal de admitir nombres.
En pocas palabras, la manipulación de nombres es un proceso mediante el cual los compiladores cambian los nombres de los identificadores en su código fuente para ayudar al linker a eliminar la ambigüedad entre esos identificadores.
Wikipedia tiene un maravilloso artículo sobre este tema con varios excelentes ejemplos.
En python, el cambio de nombre es un sistema por el cual las variables de clase tienen diferentes nombres dentro y fuera de la clase. El programador lo "activa" poniendo dos guiones bajos al comienzo del nombre de la variable.
Por ejemplo, puedo definir una clase simple con algunos miembros:
>>> class Foo(object):
... def __init__(self):
... self.x = 3
... self._y = 4
... self.__z = 5
...
En la práctica de Python, un nombre de variable que comienza con un guión bajo es "interno" y no forma parte de la interfaz de clase, por lo que los programadores no deben confiar en él. Sin embargo, todavía es visible:
>>> f = Foo()
>>> f.x
3
>>> f._y
4
Un nombre de variable que comienza con dos guiones bajos sigue siendo público, pero tiene un nombre desgarrado y, por lo tanto, es más difícil de acceder:
>>> f.__z
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: ''Foo'' object has no attribute ''__z''
Sin embargo, si sabemos cómo funciona la manipulación de nombres, podemos lograrlo:
>>> f._Foo__z
5
es decir, el nombre de clase se antepone al nombre de la variable con un guión bajo adicional.
Python no tiene concepto de miembros ''privados'' frente a ''públicos''; todo es público La manipulación de nombres es la señal más fuerte posible que un programador puede enviar para que no se pueda acceder a la variable desde fuera de la clase.
Fuente: http://sickprogrammersarea.blogspot.in/2014/03/technical-interview-questions-on-c_6.html
El mapeo de nombres es el proceso utilizado por los compiladores de C ++ que le dan a cada función en su programa un nombre único. En C ++, generalmente los programas tienen al menos algunas funciones con el mismo nombre. Por lo tanto, el cambio de nombre se puede considerar como un aspecto importante en C ++.
Ejemplo: Comúnmente, los nombres de los miembros se generan de manera única al concatenar el nombre del miembro con el de la clase, por ejemplo, dada la declaración:
class Class1
{
public:
int val;
...
};
val se convierte en algo así como:
// a possible member name mangling
val__11Class1
La mayor parte del lenguaje orientado a objetos proporciona una función de sobrecarga de funciones. Sobrecarga de funciones Si cualquier clase tiene múltiples funciones con los mismos nombres pero tipos de parámetros diferentes, entonces se dice que están sobrecargadas. La sobrecarga de funciones le permite usar el mismo nombre para diferentes funciones.
Formas de sobrecargar una función
- Al cambiar el número de Argumentos.
- Elemento de lista Al tener diferentes tipos de argumento.
¿Cómo se logra la sobrecarga de funciones con el cambio de nombre?
El compilador de C ++ distingue entre diferentes funciones cuando genera un código de objeto: cambia los nombres al agregar información sobre los argumentos según el tipo y el número de argumentos. Esta técnica de agregar información adicional para formar nombres de funciones se llama Name Mangling. El estándar de C ++ no especifica ninguna técnica particular para la creación de nombres, por lo que diferentes compiladores pueden agregar información diferente a los nombres de las funciones. He ejecutado el programa de ejemplo en 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;
}
Este programa tiene 3 funciones llamadas divertidas con diferentes en función del número de argumentos y sus tipos. El nombre de estas funciones se destruye de la siguiente manera:
ayadav@gateway1:~$ nm ./a.out |grep fun
000000000040058c W _ZN3ABC3funEff
00000000004005a0 W _ZN3ABC3funEif
000000000040057a W _ZN3ABC3funEll
- ABC es cadena de comando para el nombre de clase
- la diversión es una cadena común para el nombre de la función
- ff dos tipos de argumentos float-> f
- ll dos long-> l tipo de argumentos
- si primer argumento entero-> i y un argumento float-> f
El cambio de nombre es un medio por el cual los compiladores modifican el nombre "compilado" de un objeto, para hacerlo diferente de lo que usted especificó de manera consistente.
Esto permite a un lenguaje de programación la flexibilidad de proporcionar el mismo nombre a múltiples objetos compilados y tener una forma consistente de buscar el objeto apropiado. Por ejemplo, esto permite que existan múltiples clases con el mismo nombre en diferentes espacios de nombres (a menudo al anteponer el espacio de nombres en el nombre de la clase, etc.).
La sobrecarga de operadores y métodos en muchos idiomas lleva esto un paso más allá: cada método termina con un nombre "mutilado" en la biblioteca compilada para permitir que varios métodos en un tipo existan con el mismo nombre.