¿Por qué la gente usa tanto __ (doble subrayado) en C ++?


93

Estaba echando un vistazo a un código C ++ de código abierto y noté que se usaban muchas puntuaciones dobles en el código, principalmente al comienzo de los nombres de las variables.

return __CYGWIN__;

Solo me pregunto si hay una razón para esto, o es solo algunos estilos de código de personas. Pensaría que dificulta la lectura.


2
¿Por qué es difícil de leer? Está diseñado principalmente como un delimitador, al igual que las comillas. Según recuerdo, se usa principalmente para constantes integradas.
Matthew Scharley

1
No, no es un delimitador. Los guiones bajos se utilizan para distinguir los nombres reservados para la implementación de los nombres que puede utilizar el código fuente de los usuarios. Los usuarios pueden hacer, #define FOO 1pero no deben hacerlo #define __FOO__ 1y, por lo tanto, la implementación es libre de usar el nombre __FOO__para sus propias macros, variables, funciones, etc.
Jonathan Wakely

Creo que Matthew quiso decir que es estilística / visualmente un delimitador, no funcionalmente. Lo cual es una hipótesis interesante, pero incorrecta dado lo que he leído anteriormente y la respuesta de Jonathan.
JMI MADISON

Respuestas:


127

De Programación en C ++, Reglas y Recomendaciones :

El uso de dos guiones bajos (`__ ') en los identificadores está reservado para el uso interno del compilador de acuerdo con el estándar ANSI-C.

Los guiones bajos (`_ ') se utilizan a menudo en los nombres de las funciones de la biblioteca (como" _main "y" _exit "). Para evitar colisiones, no comience un identificador con un guión bajo.


1
Esa guía parece que fue escrita antes de que namespacese presentara.
cz

también era del imperial college london, no del estándar C ++; puede ser una buena sugerencia.
stucash

1
@cz Los espacios de nombres son irrelevantes. Un encabezado del sistema podría definir un nombre de macro que comience con un guión bajo, por ejemplo _main.
martinkunev

49

A menos que sientan que son "parte de la implementación", es decir, las bibliotecas estándar, no deberían hacerlo.

Las reglas son bastante específicas y un poco más detalladas de lo que otros han sugerido.

Todos los identificadores que contienen un guión bajo doble o comienzan con un guión bajo seguido de una letra mayúscula están reservados para el uso de la implementación en todos los ámbitos, es decir, pueden usarse para macros.

Además, todos los demás identificadores que comienzan con un guión bajo (es decir, no seguidos por otro guión bajo o una letra mayúscula) están reservados para la implementación en el ámbito global. Esto significa que puede usar estos identificadores en sus propios espacios de nombres o en definiciones de clases.

Esta es la razón por la que Microsoft usa nombres de funciones con un subrayado inicial y todo en minúsculas para muchas de sus funciones de biblioteca de tiempo de ejecución principales que no forman parte del estándar C ++. Se garantiza que estos nombres de funciones no chocarán con las funciones estándar de C ++ ni con las funciones de código de usuario.


1
En C ++ solo veo [lex.name] y para nombres globales [global.names]. ¿Puede dar referencias? gracias
a.lasram

36

De acuerdo con el estándar C ++, los identificadores que comienzan con un guión bajo están reservados para bibliotecas. Los identificadores que comienzan con dos guiones bajos están reservados para los proveedores de compiladores.


18
Más que eso: los identificadores que contienen un doble subrayado en cualquier parte están reservados. 17.4.3.1.2
Steve Jessop

En C ++ solo veo [lex.name] y para nombres globales [global.names]. ¿Puede dar referencias? gracias
a.lasram

10

Los comentarios anteriores son correctos. __Symbol__es generalmente un token mágico proporcionado por su útil proveedor de compiladores (o preprocesadores). Quizás los más utilizados son __FILE__y __LINE__, que el preprocesador C amplía para indicar el nombre de archivo actual y el número de línea. Eso es útil cuando desea registrar algún tipo de error de afirmación del programa, incluida la ubicación textual del error.


8

Es algo que no debes hacer en el código "normal". Esto asegura que los compiladores y las bibliotecas del sistema puedan definir símbolos que no colisionen con los suyos.


4

Los guiones bajos dobles están reservados para la implementación

La respuesta más votada cita Programación en C ++: Reglas y recomendaciones :

"El uso de dos guiones bajos (` __ ') en los identificadores está reservado para el uso interno del compilador de acuerdo con el estándar ANSI-C ".

Sin embargo, después de leer algunos estándares de C ++ y C, no pude encontrar ninguna mención de que los guiones bajos estuvieran restringidos solo al uso interno del compilador. Los estándares son más generales, reservando doble subrayado para la implementación .

C ++

C ++ (borrador de trabajo actual, consultado el 26 de mayo de 2019) establece en lex.name:

  • Cada identificador que contiene un doble subrayado __ o comienza con un subrayado seguido de una letra mayúscula está reservado a la implementación para cualquier uso.
  • Cada identificador que comienza con un guión bajo se reserva para la implementación para su uso como nombre en el espacio de nombres global.

C

Aunque esta pregunta es específica de C ++, he citado secciones relevantes de los estándares C 99 y 17:

C99 sección 7.1.3

  • Todos los identificadores que comienzan con un guión bajo y una letra mayúscula u otro guión bajo están siempre reservados para cualquier uso.
  • Todos los identificadores que comienzan con un guión bajo siempre se reservan para su uso como identificadores con alcance de archivo en los espacios de nombre ordinario y de etiqueta.

C17 dice lo mismo que C99.

¿Qué es la implementación ?

Para C / C ++, la implementación se refiere libremente a los recursos establecidos necesarios para producir un ejecutable a partir de los archivos fuente del usuario. Esto incluye:

  • preprocesador
  • compilador
  • enlazador
  • biblioteca estándar

Implementaciones de ejemplo

Hay varias implementaciones diferentes de C ++ mencionadas en Wikipedia . (sin vínculo de ancla, ctrl + f "implementación")

Aquí hay un ejemplo de la implementación de C / C ++ de Digital Mars que reserva algunas palabras clave para una característica de ellos.


3

Además de las bibliotecas sobre las que respondieron muchas otras personas, algunas personas también nombran macros o valores #define para usar con el preprocesador. Esto facilitaría el trabajo y podría haber permitido solucionar errores en compiladores más antiguos.

Como otros mencionaron, ayuda a prevenir la colisión de nombres y ayuda a delinear entre las variables de la biblioteca y las suyas.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.