Pregunta ¿Cuáles son las reglas sobre el uso de un guión bajo en un identificador de C ++?


Es común en C ++ nombrar las variables miembro con algún tipo de prefijo para denotar el hecho de que son variables miembro, en lugar de variables locales o parámetros. Si proviene de un fondo de MFC, probablemente use m_foo. También he visto myFoo de vez en cuando.

C # (o posiblemente solo .NET) parece recomendar el uso de un guion bajo, como en _foo. ¿Esto está permitido por el estándar de C ++?


800
2017-10-23 07:02


origen


Respuestas:


Las reglas (que no cambiaron en C ++ 11):

  • Reservado en cualquier ámbito, incluso para su uso como macros de implementación:
    • identificadores que comienzan con un guión bajo seguido de inmediato por una letra mayúscula
    • identificadores que contienen guiones bajos adyacentes (o "doble guión bajo")
  • Reservado en el espacio de nombres global:
    • identificadores que comienzan con un guion bajo
  • Además, todo en el std el espacio de nombres está reservado. (Sin embargo, está permitido agregar especializaciones de plantilla).

Del Estándar C ++ 2003:

17.4.3.1.2 Nombres globales [lib.global.names]

Ciertos conjuntos de nombres y firmas de funciones siempre se reservan para la implementación:

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

165) Dichos nombres también están reservados en el espacio de nombres ::std (17.4.3.1).

Como C ++ se basa en el estándar C (1.1 / 2, C ++ 03) y C99 es una referencia normativa (1.2 / 1, C ++ 03), estos también se aplican, a partir del Estándar C de 1999:

7.1.3 Identificadores reservados

Cada encabezado declara o define todos los identificadores listados en su subcláusula asociada, y   declara o define opcionalmente los identificadores enumerados en su subcláusula de instrucciones de biblioteca futura asociada e identificadores que siempre se reservan para cualquier uso o para uso como identificadores de alcance de archivo.

  • Todos los identificadores que comienzan con un guión bajo y una letra mayúscula u otra   los subrayados siempre están reservados para cualquier uso.
  • Todos los identificadores que comienzan con un guión bajo siempre están reservados para su uso como identificadores   con alcance de archivo tanto en el espacio ordinario como en el espacio de nombre de etiqueta.
  • Cada nombre de macro en cualquiera de los siguientes apartados (incluida la biblioteca futura)   direcciones) está reservado para su uso como se especifica si se incluye alguno de sus encabezados asociados;   a menos que se indique explícitamente lo contrario (ver 7.1.4).
  • Todos los identificadores con enlace externo en cualquiera de los siguientes apartados (incluido el   futuras direcciones de la biblioteca) siempre se reservan para su uso como identificadores con   enlace.154
  • Cada identificador con alcance de archivo enumerado en cualquiera de los siguientes apartados (incluido el   futuras direcciones de la biblioteca) está reservado para su uso como un nombre de macro y como un identificador con   alcance del archivo en el mismo espacio de nombre si se incluye alguno de sus encabezados asociados.

No hay otros identificadores reservados. Si el programa declara o define un identificador en un   contexto en el que está reservado (a excepción de lo permitido por 7.1.4), o define una reserva   identificador como nombre de macro, el comportamiento no está definido.

Si el programa elimina (con #undef) cualquier definición de macro de un identificador en el primer   grupo mencionado anteriormente, el comportamiento no está definido.

154) La lista de identificadores reservados con enlaces externos incluye errno, math_errhandling, setjmpy va_end.

Se pueden aplicar otras restricciones. Por ejemplo, el estándar POSIX reserva una gran cantidad de identificadores que es probable que aparezcan en el código normal:

  • Nombres que comienzan con un capital E seguido de un dígito o una letra mayúscula:
    • se puede usar para nombres de código de error adicionales.
  • Nombres que comienzan con cualquiera is o to seguido de una letra minúscula
    • se puede usar para pruebas de caracteres adicionales y funciones de conversión.
  • Nombres que comienzan con LC_ seguido de una letra mayúscula
    • se puede usar para macros adicionales que especifiquen atributos de configuración regional.
  • Nombres de todas las funciones matemáticas existentes con sufijo f o l están reservados
    • para funciones correspondientes que operan en flotante y argumentos dobles largos, respectivamente.
  • Nombres que comienzan con SIG seguido de una letra mayúscula están reservados
    • para nombres de señal adicionales.
  • Nombres que comienzan con SIG_ seguido de una letra mayúscula están reservados
    • para acciones de señal adicionales.
  • Nombres comenzando con str, mem, o wcs seguido de una letra minúscula están reservados
    • para cadenas adicionales y funciones de matriz.
  • Nombres comenzando con PRI o SCN seguido de cualquier letra minúscula o X están reservados
    • para macros especificadores de formato adicionales
  • Nombres que terminan con _t están reservados
    • para nombres de tipos adicionales.

Si bien el uso de estos nombres para sus propios fines en este momento podría no ser un problema, aumentan la posibilidad de conflicto con las versiones futuras de ese estándar.


Personalmente, simplemente no comienzo identificadores con guiones bajos. Nueva adición a mi regla: no use doble guión bajo en ninguna parte, lo que es fácil ya que rara vez uso el guión bajo.

Después de investigar sobre este artículo, ya no termino mis identificadores con _t ya que está reservado por el estándar POSIX.

La regla sobre cualquier identificador que termine con _t me sorprendió mucho Creo que es un estándar POSIX (no estoy seguro todavía) en busca de aclaraciones y capítulo y verso oficiales. Esto es de la Manual libtool de GNU, enumerando nombres reservados.

CesarB proporcionó el siguiente enlace a la POSIX 2004 símbolos reservados y notas 'que muchos otros prefijos y sufijos reservados ... se pueden encontrar allí'. los POSIX 2008 los símbolos reservados se definen aquí. Las restricciones son algo más matizadas que las anteriores.


739
2017-10-23 07:27



Las reglas para evitar la colisión de nombres están en el estándar de C ++ (ver el libro de Stroustrup) y mencionadas por los gurús de C ++ (Sutter, etc.).

Regla personal

Como no quería ocuparme de los casos, y quería una regla simple, diseñé un personal uno que es a la vez simple y correcto:

Al nombrar un símbolo, evitará la colisión con el compilador / OS / bibliotecas estándar si usted:

  • nunca inicie un símbolo con un guión bajo
  • nunca nombre un símbolo con dos guiones bajos consecutivos en el interior.

170
2017-10-23 07:06



De MSDN:

El uso de dos caracteres de subrayado secuenciales (__) al comienzo de un identificador, o un subrayado inicial único seguido de una letra mayúscula, está reservado para las implementaciones de C ++ en todos los ámbitos. Debe evitar el uso de un guión bajo seguido de una letra minúscula para los nombres con alcance de archivo debido a posibles conflictos con los identificadores reservados actuales o futuros.

Esto significa que puede usar un guión bajo único como prefijo de variable miembro, siempre que esté seguido de una letra minúscula.

Esto aparentemente se toma de la sección 17.4.3.1.2 del estándar de C ++, pero no puedo encontrar una fuente original para el estándar completo en línea.

Ver también esta pregunta.


28
2017-11-14 20:03



En cuanto a la otra parte de la pregunta, es común poner el guión bajo en el fin del nombre de la variable para que no choque con nada interno.

Hago esto incluso dentro de clases y espacios de nombres porque solo tengo que recordar una regla (comparada con "al final del nombre en el alcance global, y el comienzo del nombre en cualquier otro lugar").


21
2017-10-23 07:05



Sí, los guiones bajos se pueden usar en cualquier parte de un identificador. Creo que las reglas son: cualquiera de a-z, A-Z, _ en el primer personaje y aquellos + 0-9 para los siguientes personajes.

Los prefijos bajo subrayado son comunes en el código C: un subrayado único significa "privado", y los guiones bajos dobles generalmente están reservados para el uso del compilador.


2