Preguntas sobre el nombre del mangling en C++
compilation linker (5)
Estoy tratando de aprender y entender la manipulación de nombres en C ++. Aquí hay algunas preguntas:
(1) De devx
Cuando una función global está sobrecargada, el nombre modificado generado para cada versión sobrecargada es único. La manipulación de nombres también se aplica a las variables. Por lo tanto, una variable local y una variable global con el mismo nombre dado por el usuario aún obtienen distintos nombres mutilados.
¿Hay otros ejemplos que utilizan la manipulación de nombres, además de funciones de sobrecarga y variables locales y globales con el mismo nombre?
(2) De Wiki
Surge la necesidad de que el lenguaje permita que diferentes entidades sean nombradas con el mismo identificador, siempre y cuando ocupen un espacio de nombres diferente (donde un espacio de nombres generalmente se define mediante un módulo, una clase o una directiva explícita de espacio de nombres).
No entiendo bien por qué la mutilación de nombres solo se aplica a los casos en que los identificadores pertenecen a diferentes espacios de nombres, ya que las funciones de sobrecarga pueden estar en el mismo espacio de nombres y las variables locales y globales del mismo nombre también pueden estar en el mismo espacio. ¿Cómo entender esto?
¿Las variables con el mismo nombre pero en diferentes ámbitos también utilizan la manipulación de nombres?
(3) ¿C tiene nombre mangling? Si no lo hace, ¿cómo puede manejar el caso cuando algunas variables globales y locales tienen el mismo nombre? C no tiene funciones de sobrecarga, ¿verdad?
¡Gracias y saludos!
Fuente: http://sickprogrammersarea.blogspot.in/2014/03/technical-interview-questions-on-c_6.html
La manipulación 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, la manipulación de nombres se puede considerar como un aspecto importante en C ++.
Ejemplo: Comúnmente, los nombres de miembros se generan de forma ú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
Técnicamente, es "decorar". Suena menos burdo, pero también es una especie de CreditInterest
que implica que CreditInterest
podría reorganizarse en IntCrederestit
mientras que lo que realmente sucede es más parecido a _CreditInterest@4
que es justo decir "decorado" más que destrozado. Dicho esto, también lo llamo mangling :-) pero encontrará más información técnica y ejemplos si busca "decoración de nombres C ++".
¿Hay otros ejemplos que utilizan la manipulación de nombres, además de funciones de sobrecarga y variables locales y globales con el mismo nombre?
C ++ maneja todos los símbolos, siempre. Es más fácil para el compilador. Por lo general, la mutilación codifica algo sobre la lista de parámetros o los tipos, ya que son las causas más comunes de la necesidad de mutilar.
C no se ríe. El alcance se utiliza para controlar el acceso a variables locales y globales del mismo nombre.
Mangling es simplemente cómo el compilador mantiene feliz al enlazador.
En C, no puedes tener dos funciones con el mismo nombre, pase lo que pase. Así que eso es lo que el enlazador fue escrito para asumir: nombres únicos. (Puede tener funciones estáticas en diferentes unidades de compilación, porque sus nombres no son de interés para el enlazador).
En C ++, puede tener dos funciones con el mismo nombre siempre que tengan diferentes tipos de parámetros. Así que C ++ combina el nombre de la función con los tipos de alguna manera. De esa manera, el enlazador los ve con nombres diferentes.
Tenga en cuenta que no importa cómo se mancille el nombre y, de hecho, cada compilador lo hace de manera diferente. Lo único que importa es que cada función con el mismo nombre base se hace de alguna manera única para el enlazador.
Ahora puede ver que agregar espacios de nombres y plantillas a la mezcla continúa extendiendo el principio.
C no realiza la manipulación de nombres, aunque sí precompila un guión bajo a nombres de funciones, por lo que printf(3)
es en realidad _printf
en el objeto libc.
En C ++ la historia es diferente. La historia de esto es que originalmente Stroustrup creó "C con clases" o cfront , un compilador que traduciría C ++ temprano a C. Luego, el resto de las herramientas: el compilador de C y el enlazador que usaríamos para producir código objeto. Esto implicaba que los nombres de C ++ debían traducirse a nombres de C de alguna manera. Esto es exactamente lo Wiki hace la Wiki . Proporciona un nombre único para cada miembro de la clase y función / variable global / espacio de nombres, por lo que los nombres de los espacios de nombres y clases (para resolución) y los tipos de argumentos (para sobrecargas) se incluyen de alguna manera en los nombres finales del vinculador.
Esto es muy fácil de ver con herramientas como nm(1)
: compile su fuente de C ++ y observe los símbolos generados. Lo siguiente está en OSX con GCC:
namespace zoom
{
void boom( const std::string& s )
{
throw std::runtime_error( s );
}
}
~$ nm a.out | grep boom
0000000100001873 T __ZN4zoom4boomERKSs
Tanto en C como en C ++, las variables locales (automáticas) no producen símbolos, sino que viven en registros o en la pila.
Editar:
Las variables locales no tienen nombres en el archivo de objeto resultante por la simple razón de que el vinculador no necesita conocerlas. Así que sin nombre, sin destrozar. Todo lo demás (que el vinculador tiene que ver) es manipulado por el nombre en C ++.