tutorial programming programacion online language book c language-history

programming - ¿Por qué los compiladores de C anteponen los guiones bajos a los nombres externos?



c++ language (5)

Era una práctica común para los compiladores de C anteponer un subrayado inicial a todos los identificadores de programas de alcance externo para evitar conflictos con las contribuciones del soporte de lenguaje de tiempo de ejecución.

Si el compilador proporciona el soporte de tiempo de ejecución, ¡podría pensar que tendría más sentido anteponer un guión bajo a los pocos identificadores externos en el soporte de tiempo de ejecución en su lugar!

Cuando los compiladores C aparecieron por primera vez, la alternativa básica a la programación en C en esas plataformas era la programación en lenguaje ensamblador, y era (y de vez en cuando aún es) útil vincular archivos de objetos escritos en ensamblador y C. Así que realmente (IMHO) El subrayado añadido a los identificadores C externos era para evitar conflictos con los identificadores en su propio código de ensamblaje.

(Consulte también la extensión de etiquetas asm de GCC , y tenga en cuenta que este subrayado anterior se puede considerar una forma simple de alteración de nombres . Los lenguajes más complicados como C ++ utilizan un tratamiento de nombres más complicado, pero aquí es donde comenzó).

He estado trabajando en C por tanto tiempo que el hecho de que los compiladores normalmente agreguen un guión bajo al comienzo de un extern se acaba de entender ... Sin embargo, otra pregunta SO hoy me hizo preguntarme sobre la verdadera razón por la cual se agrega el subrayado. Un artículo de wikipedia afirma que una razón es:

Era una práctica común para los compiladores de C anteponer un subrayado inicial a todos los identificadores de programas de alcance externo para evitar conflictos con las contribuciones del soporte de lenguaje de tiempo de ejecución.

Creo que hay al menos un núcleo de verdad en esto, pero tampoco parece responder a la pregunta, ya que si se agrega el subrayado a todos los externos, no ayudará mucho a prevenir los enfrentamientos.

¿Alguien tiene buena información sobre la justificación del subrayado inicial?

¿Es el guión bajo agregado parte de la razón por la cual la llamada al sistema creat() Unix no termina con una ''e''? He oído que los primeros enlazadores en algunas plataformas tenían un límite de 6 caracteres para los nombres. Si ese es el caso, anteponer un guión bajo a los nombres externos parecería una idea muy loca (ahora solo tengo 5 personajes para jugar ...).


De la Wikipedia :

Era una práctica común para los compiladores de C anteponer un guión bajo principal a todos los identificadores de programas de alcance externo para evitar conflictos con las contribuciones del soporte de lenguaje de tiempo de ejecución. Además, cuando el compilador C / C ++ necesitaba introducir nombres en el enlace externo como parte del proceso de traducción, estos nombres a menudo se distinguían con una combinación de varios guiones bajos iniciales o finales.

Esta práctica se codificó más tarde como parte de los estándares de lenguaje C y C ++, en los que el uso de guiones bajos principales se reservó para la implementación.

De lo que siempre escucho es para evitar conflictos entre nombres. No para otras variables externas, sino para que cuando utilice una biblioteca no entre en conflicto con los nombres de las variables de código de usuario.


La función principal no es el punto de entrada real de un ejecutable. Algunos archivos vinculados estáticamente tienen el punto de entrada real que finalmente llama a main, y los archivos vinculados estáticamente poseen el espacio de nombres que no comienza con un guión bajo. En mi sistema, en / usr / lib, hay gcrt1.o, crt1.o y dylib1.o entre otros. Cada uno de ellos tiene una función de "inicio" sin un guión bajo que eventualmente llamará al punto de entrada "_main". Todo lo demás además de esos archivos tiene un alcance externo. La historia tiene que ver con mezclar assembler y C en un proyecto, donde todo C se considera externo.


si el compilador c siempre precedió un guión bajo antes de cada símbolo, entonces el código de inicio / c-runtime (que generalmente está escrito en ensamblaje) puede usar etiquetas y símbolos que no comienzan con un guión bajo (como el símbolo ''start '').

incluso si escribe una función start () en el código c, se genera como _start en la salida object / asm. (Tenga en cuenta que en este caso, no hay posibilidad de que el código c genere un símbolo que no comience con un guión bajo), por lo que el codificador no tiene que preocuparse por inventar símbolos oscuros improbables (como $ _dontuse42% $) para cada uno de sus variables / etiquetas globales.

entonces el enlazador no se queja de un choque de nombres, y el programador está contento. :)

lo siguiente es diferente de la práctica del compilador anteponiendo un subrayado en sus formatos de salida.

Esta práctica se codificó más tarde como parte de los estándares de lenguaje C y C ++, en los que el uso de guiones bajos principales se reservó para la implementación.

esa es una convención seguida, para las bibliotecas de sistemas c y otros componentes del sistema. (y para cosas como __FILE__, etc.)

(tenga en cuenta que dicho símbolo (ej .: _time) puede dar como resultado 2 guiones bajos (__time) en la salida generada)