Es común que en C++, a nombre de las variables miembro con algún tipo de prefijo para indicar el hecho de que son las variables miembro, en lugar de variables locales o parámetros. Si has de venir de una MFC fondo, es probable que use m_foo. También he visto myFoo de vez en cuando.

C# (o, posiblemente, sólo .NET) parece recomendar el uso de sólo un carácter de subrayado, como en _foo. Es esto permitido por el estándar de C++?

La glibc página de manual sobre la que se puede encontrar en gnu.org/software/libc/manual/html_node/Reserved-Names.html Editar: véase también opengroup.org/onlinepubs/009695399/functions/xsh_chap02_02.html
Sólo para señalar que el desconocimiento de estas normas no implica necesariamente que el código no se puede compilar o ejecutar, pero es probable que su código no será portable a diferentes compiladores y versión, ya que no se puede garantizar que no va a ser el nombre de los enfrentamientos . Para respaldar esto sé de cierto implementación de un importante sistema que ha estado usando como una convención de nomenclatura _ de la letra mayúscula en todas partes. Allí donde no hay errores debido a esto. Por supuesto que es una mala práctica.

OriginalEl autor Roger Lipscombe | 2008-10-23

5 Comentarios

  1. 755

    Las reglas (que no se modifica en C++11):

    • Reservados en cualquier ámbito, incluso para uso como la aplicación macros:
      • identificadores que comienzan con un guión bajo seguido inmediatamente por una letra mayúscula
      • identificadores adyacentes que contienen caracteres de subrayado (o «doble guión bajo»)
    • Reservado en el espacio de nombres global:
      • identificadores que comienzan con un guión bajo
    • También, todo en el std espacio de nombres reservados. (Se le permite añadir plantilla de especializaciones, sin embargo.)

    Desde el 2003 Estándar de C++:

    17.4.3.1.2 de nombres Global [lib.global.nombres]

    Ciertos conjuntos de nombres y firmas de función están siempre reservados para la implementación:

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

    165) Tales nombres se reservan en el espacio de nombres ::std (17.4.3.1).

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

    7.1.3 identificadores Reservados

    Cada encabezado declara o que define todos los identificadores de los mencionados en sus asociados inciso, y
    opcionalmente declara o que define los identificadores de los mencionados en sus futuros asociados de la biblioteca de las direcciones inciso e identificadores que siempre se reservan para el uso o para el uso como el ámbito de los archivos de los identificadores.

    • Todos los identificadores que comienzan con un guión bajo y una letra mayúscula o otro
      subrayado siempre están reservados para cualquier uso.
    • Todos los identificadores que comienzan con un guión bajo están siempre reservados para utilizar como identificadores
      con el ámbito de los archivos, tanto el ordinario y el nombre de la etiqueta espacios.
    • Cada nombre de la macro en cualquiera de las siguientes subcláusulas (incluido el futuro de la biblioteca
      las direcciones) está reservado para el uso como se especifica si cualquiera de sus asociados encabezados se incluye;
      a menos que se indique explícitamente lo contrario (véase 7.1.4).
    • Todos los identificadores con vinculación externa en cualquiera de las siguientes subcláusulas (incluyendo la
      el futuro de la biblioteca de direcciones) siempre están reservados para su uso como identificadores externos
      la vinculación.154
    • Cada identificador con el ámbito de archivo enumerados en cualquiera de las siguientes subcláusulas (incluyendo la
      el futuro de la biblioteca de direcciones) está reservado para el uso como un nombre de macro y como un identificador con
      ámbito de los archivos en el mismo espacio de nombres si cualquiera de sus asociados encabezados incluido.

    No otros identificadores son reservados. Si el programa declara o define un identificador en un
    contexto en el que se reservados (con excepción de lo permitido por la 7.1.4), o define una reservados
    identificador como un nombre de macro, el comportamiento es indefinido.

    Si el programa elimina (con #undef) cualquier definición de macro de un identificador en la primera
    grupo enumerados anteriormente, el comportamiento es indefinido.

    154) La lista de identificadores reservados con vinculación externa incluye errno, math_errhandling, setjmp, y va_end.

    Otras restricciones pueden aplicar. Por ejemplo, el estándar POSIX se reserva una gran cantidad de identificadores que son propensos a mostrar en normal código:

    • Nombres que comienzan con un capital E seguido de un dígito o letra en mayúsculas:
      • puede ser usado para nombres de dominio con código de error adicional.
    • Nombres que comienzan con is o to seguido por una letra minúscula
      • puede ser utilizado para el carácter adicional de pruebas y las funciones de conversión.
    • Nombres que comienzan con LC_ seguido por una letra mayúscula
      • puede ser utilizado para macros adicionales especificación de atributos de configuración regional.
    • Los nombres de todas las funciones matemáticas con el sufijo f o l están reservados
      • para las correspondientes funciones que operan en float y long double argumentos, respectivamente.
    • Nombres que comienzan con SIG seguido por una letra mayúscula están reservados
      • adicional de la señal de nombres.
    • Nombres que comienzan con SIG_ seguido por una letra mayúscula están reservados
      • de señal adicional de acciones.
    • Nombres que comienzan con str, mem, o wcs seguido por una letra minúscula son reservados
      • de cadena adicionales y funciones de la matriz.
    • Nombres que comienzan con PRI o SCN seguido de cualquier letra minúscula o X están reservados
      • adicionales especificador de formato de macros
    • Los nombres que terminan con _t están reservados
      • adicional tipo de nombres.

    Mientras que el uso de estos nombres para sus propios propósitos ahora podría no causar un problema, ellos plantean la posibilidad de conflicto con las futuras versiones de este estándar.


    Personalmente no estoy de inicio identificadores con caracteres de subrayado. Nueva incorporación a mi regla: no use doble subraya en cualquier lugar, que es fácil que yo rara vez uso de subrayado.

    Después de hacer investigación en este artículo ya no tengo que terminar mi identificadores con _t
    como esto está reservado por el estándar POSIX.

    La regla sobre cualquier identificador, terminando con _t me sorprendió mucho. Creo que es un estándar POSIX (no estoy seguro todavía) en busca de una aclaración oficial y el capítulo y el versículo. Esto es de la GNU libtool manual, listado de nombres reservados.

    CesarB proporciona el siguiente enlace a la POSIX 2004 reservados símbolos y notas «a la que muchos otros reservados prefijos y sufijos … puede encontrar allí’. El
    POSIX 2008 reservados símbolos están definidos aquí. Las restricciones son algo más sutiles que los de arriba.

    El estándar de C++ no «importar» la C uno, no? Que la importación de ciertos encabezados, pero no el lenguaje como un todo, o de las reglas de nomenclatura, por lo que yo sé. Pero sí, el _t uno que me sorprendió también. Pero ya que es C, sólo se pueden aplicar a la global ns. Deben ser seguros para su uso _t dentro de las clases como he leído
    El Estándar de C++ no «importar» el C Estándar. referencias el C Estándar. La biblioteca de C++ introducción dice: «asimismo, La biblioteca pone a su disposición las instalaciones de la Norma C» de la Biblioteca. Lo hace mediante la inclusión de encabezados de la biblioteca Estándar de C con los cambios pertinentes, pero no por la «importación». El Estándar de C++ dispone de un conjunto de reglas que describen los nombres reservados. Si un nombre reservado en C debe ser reservada en C++, que es el lugar para decir esto. Pero el Estándar de C++ no lo dice. Así que no creo que las cosas reservadas en C están reservadas en C++ – pero yo podría estar equivocado.
    Esto es lo que he encontrado acerca de la «_t» tema: n1256 (C99 TC3) dice: «Typedef nombres que comienzan con int o uint y terminando con _t» están reservados. Creo que todavía permite el uso de nombres como «foo_t» – pero creo que estas son reservados por POSIX.
    Así que la «tolerancia» es reservado por POSIX, ya que comienza con ‘a’ + una letra minúscula? Apuesto a que muchos de código se rompe esta regla!
    El estándar de C++ se define en términos de la C estándar. Básicamente dice que el C++ C con estas diferencias y adiciones.» Tonterías! C++ sólo hace referencia al estándar de C en [basic.fundamentales] y la biblioteca. Si lo que dices es cierto, ¿de dónde C++ decir que _Bool y _Imaginary no existe en C++? El lenguaje C++ son definidos de forma explícita, no en términos de «ediciones» C, de lo contrario, la norma podría ser mucho más corto!

    OriginalEl autor

  2. 176

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

    Personal de la regla

    Porque yo no quiero lidiar con los casos, y quería una regla simple, he diseñado un personal uno que es a la vez simple y correcta:


    Cuando el nombramiento de un símbolo, de evitar la colisión con el compilador/OS/bibliotecas estándar si:

    • nunca inicie un símbolo con un carácter de subrayado
    • nunca el nombre de un símbolo con dos guiones bajos consecutivos en el interior.

    Por supuesto, poner el código en un único espacio de nombres ayuda a evitar la colisión, pero no protegen contra el mal de macros)

    Algunos ejemplos

    (Yo uso de macros, porque ellos son los más contaminantes de C/C++ símbolos, pero podría ser cualquier cosa, desde el nombre de la variable para el nombre de la clase)

    #define _WRONG
    #define __WRONG_AGAIN
    #define RIGHT_
    #define WRONG__WRONG
    #define RIGHT_RIGHT
    #define RIGHT_x_RIGHT

    Extractos de C++0x proyecto de

    De la n3242.pdf archivo (espero que el final de texto estándar a ser similar):

    17.6.3.3.2 de nombres Global [global.nombres]

    Ciertos conjuntos de nombres y firmas de función están siempre reservados para la implementación:

    — Cada nombre que contiene un doble guión bajo _ _ o comienza con un guión bajo seguido por una letra mayúscula (2.12) es reservado para la implementación de cualquier uso.

    — Cada nombre que comienza con un carácter de subrayado está reservado a la aplicación para su uso como un nombre en el espacio de nombres global.

    Pero también:

    17.6.3.3.5 definido por el Usuario literal sufijos [usrlit.sufijo]

    Literal sufijo identificadores que no comienzan con un guión bajo están reservados para el futuro de la normalización.

    Esta última cláusula es confuso, a menos que usted considere que un nombre que comienza con un carácter de subrayado y seguido de una letra minúscula estaría bien si no definido en el espacio de nombres global…

    ¿Qué acerca de #define __WRONG_AGAIN__? es esto un error?
    __WRONG_AGAIN__ contiene dos guiones bajos consecutivos (dos al principio y dos al final), así que esto está mal de acuerdo a la norma.
    ¿por qué es #define WRONG__WRONG mal?
    WRONG__WRONG contiene dos guiones bajos consecutivos (dos en el centro), así que esto está mal de acuerdo a la norma
    poner el código en un único espacio de nombres ayuda a evitar la colisión, también: pero esto no es suficiente, ya que el identificador puede chocar con una palabra clave, independientemente de alcance (por ejemplo, __attribute__ para GCC).

    OriginalEl autor paercebal

  3. 30

    De MSDN:

    Uso de dos secuencial de caracteres de subrayado ( __ ) al principio de un identificador, o una sola de subrayado seguido de una letra mayúscula, está reservado para C++ implementaciones en todos los ámbitos. Usted debe evitar el uso de uno de subrayado seguido de una letra en minúsculas para los nombres de archivo de alcance debido a los posibles conflictos con el actual o futuro identificadores reservados.

    Esto significa que usted puede utilizar un solo carácter de subrayado como una variable de miembro de prefijo, mientras es seguido por una letra minúscula.

    Al parecer, esto es tomado 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.

    Me encontré con un texto similar en n3092.pdf (el proyecto de C++0x estándar) en la sección: «17.6.3.3.2 de nombres Global»
    Curiosamente, esta parece ser la única respuesta que tiene directa, concisa respuesta a la pregunta.
    En realidad, no lo es, ya que es saltarse la regla de no tener ninguna identificadores con un subrayado en el espacio de nombres global. Consulte Roger respuesta. Me gustaría ser muy cautelosos a la hora de las citas de MS VC docs como una autoridad en el estándar de C++.
    Me estaba refiriendo a «se puede utilizar un único carácter de subrayado como una variable de miembro de prefijo, mientras es seguido por una letra minúscula» en esta respuesta, que responde a la pregunta en el texto de la pregunta directamente y de forma concisa, sin ser ahogado en una pared de texto.
    En primer lugar, yo aún consideran que la falta de cualquier indicio de que la misma regla no se aplica para el espacio de nombres global de un fracaso. Lo que es peor, sin embargo, es que adyacente subraya están prohibidos, no sólo al comienzo, sino lugar, un identificador. Así que esta respuesta no es más que la omisión de un hecho, pero en realidad hace que al menos uno activamente mal reclamación. Como ya he dicho, en referencia a la MSVC docs es algo que yo no haría, a menos que la pregunta es único acerca de VC.

    OriginalEl autor Roger Lipscombe

  4. 21

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

    Hago esto incluso dentro de las clases y espacios de nombres, porque yo, a continuación, sólo tiene que recordar una regla (en comparación con «al final del nombre en el ámbito global, y el principio del nombre en todas partes»).

    OriginalEl autor Max Lybbert

  5. 1

    Sí, pone de relieve puede ser utilizado en cualquier lugar en un identificador. Creo que las reglas son: los de la a-z, a-Z, _ en el primer carácter y los + 0-9 para los siguientes caracteres.

    Subrayado prefijos son comunes en código C — un solo carácter de subrayado significa «privado», y el doble de relieve son generalmente reservados para su uso por el compilador.

    Son comunes en las bibliotecas. Ellos no deben ser comunes en el código de usuario.
    Estoy de acuerdo con Martin en este caso.
    La gente de escribir bibliotecas en C, que usted sabe.
    «Sí, pone de relieve puede ser utilizado en cualquier lugar en un identificador.» Esto es malo para el global de los identificadores. Consulte Roger respuesta.
    -1 «Sí, pone de relieve puede ser utilizado en cualquier lugar en un identificador.» No.

    OriginalEl autor John Millikin

Dejar respuesta

Please enter your comment!
Please enter your name here