¿Existe una convención de capitalización común en C ++? [cerrado]

13

Hago mucho trabajo en Python y Java, y ambos lenguajes tienen convenciones bastante comunes (aunque no universales) sobre cómo se deben usar las mayúsculas en los identificadores: ambos se usan PascalCasepara nombres de clase y ALL_CAPSpara constantes "globales", pero para otros identificadores un muchos usos de código Java, mixedCasemientras que muchos usos de código Python underscore_delimiters. Sé que ningún idioma o biblioteca impone una capitalización en particular, pero descubrí que cuando me apego a las convenciones estándar para el idioma que estoy usando, mi código parece mucho más legible.

Ahora estoy comenzando un proyecto en C ++, y me gustaría aplicar la misma idea. ¿Hay alguna convención más común para la capitalización que deba conocer?

David Z
fuente
El problema con camelCase es que no funciona bien con el preprocesador. No es un gran problema, especialmente porque el preprocesador generalmente se puede evitar.
Pubby
Tuve que enfrentar esta decisión hace solo unos días. Al final, fue obvio, ya que tanto la biblioteca estándar como el boost usan underscore_lowercase_delimiters. Como uso boost como un refuerzo STL, se rociará todo sobre mi código. Otras bibliotecas que uso que son PascalCase (SFML) se pueden contener más fácilmente, por lo que cualquier método es bastante estándar.
Max
@ Pubby8: por curiosidad: ¿cómo choca CamelCase con el preprocesador?
Joachim Sauer
@JoachimSauer Las palabras individuales en camelCase pueden tener un caso diferente, pero las macros no pueden cambiar el caso. Esto se convierte en un problema si desea una macro que tome parte de una palabra como argumento; es posible que deba proporcionar ambos casos como argumentos: macro (x, X). Es un problema bastante menor, pero debe saberse si tiene la intención de utilizar el preprocesador.
Pubby

Respuestas:

27

¿Hay alguna convención más común para la capitalización que deba conocer?

C ++ se basa en C, que es lo suficientemente viejo como para haber desarrollado un montón de convenciones de nomenclatura para cuando se inventó C ++. Luego, C ++ agregó algunos, y C tampoco ha estado inactivo pensando en nuevos. Agregue a eso los muchos lenguajes derivados de C, que desarrollaron aún más las convenciones de nomenclatura de C de su inventor, hasta el punto de volver a fertilizar en C y C ++ ... En otras palabras: C ++ no tiene una, sino muchas de esas convenciones.

Sin embargo, si está buscando la convención de nomenclatura única , también podría mirar la convención de nomenclatura de la biblioteca estándar , porque esta es la única que todos los desarrolladores de C ++ tendrán que conocer y estar acostumbrados.

Sin embargo, lo que sea que use la regla más importante es: ¡ Sea consistente!

Curiosamente, aunque comencé con una combinación de PascalCase y camelCase, y participé en numerosos proyectos con convenciones de nomenclatura aún más numerosas, a lo largo de los años descubrí que me atasqué cada vez más con la convención de biblioteca estándar. No me preguntes por qué.

sbi
fuente
Gracias por la información ... ¿entonces la biblioteca estándar es guiones bajos? (¿al menos más que cualquier otra cosa?) Estaba pensando en ese sentido, pero fue algo difícil de distinguir debido a cosas como iostream en las que la mitad de los nombres de los métodos parecen ser el mismo tipo de fragmentos de palabras mezcladas que ANSI C :-P
David Z
55
@David: la biblioteca iostreams tiene probablemente 25 años y (a excepción de C lib, o curso) podría ser la parte más antigua de C ++ std lib. Con suerte, nadie en su sano juicio lo diseñaría como está hoy en día, y con suerte, incluso aquellos que no estén en su sano juicio no elegirían identificadores de la forma en que se usan en la biblioteca de flujos. (Vamos, hay funciones nombradas egptr, sputny uflowtambién underflow. ¡Eso es simplemente gracioso!) De todos modos, sí, la biblioteca estándar hoy en día usa all_lowercase_with_underscores.
sbi
@sbi Descubrí que la biblioteca iostream ya no se considera una biblioteca estándar para C ++. Y como mencionas, sus identificadores no son útiles como una convención de programación ;-)
umlcat
2
@umlcat: la biblioteca iostreams (en su plantilla de la aceptada para C ++ 03) se considera definitivamente parte de la biblioteca estándar de C ++.
sbi
También he seguido la misma ruta. Creo que la razón que tengo es camelCase es un poco más fácil de escribir y quería ser vago allí. Más tarde supe que pasaba más tiempo leyendo y refactorizando mi código que escribiéndolo, y snake_case es más fácil de leer. Entonces se trata de minimizar el gasto de energía. Ahora estoy jugando con nombres en minúsculas para las clases. No es convencional, sin embargo, creo que cambiarlo y poner en mayúsculas las instancias importantes y los tipos en minúsculas en realidad mejora la legibilidad de mi código. Estoy pensando que tal vez este es el camino a seguir. Lo que es importante en mayúscula, como en humanitario.
PSkocik
19

Primero aceptemos que ALL UPPERCASE es una monstruosidad y debe minimizarse.

Por lo tanto, en C y C ++ se usa como una convención para macros, y solo para macros, porque las macros son igualmente feas, por no decir mal.

Los primeros C no tenían constante, por lo que las constantes debían expresarse como macros. Además, en aquellos primeros días, los programas eran mucho más cortos, por lo que las prácticas que hoy no son buenas podrían usarse (por ejemplo, el IIRC Brian Kernighan escribió código con muchas macros no mayúsculas). Y también, en aquellos días existían teclados que no tenían letras minúsculas; Usé uno de estos, en la computadora noruega Tandberg EC-10, alrededor de 1980 o 1979, creo que era.

Entonces, Java recogió la convención en mayúscula para constantes desde principios de C. Mientras tanto, y tal vez incluso antes de eso (no estoy seguro de la cronología aquí), C obtuvo constantes. Sin embargo, aunque, por supuesto, algunos / muchos programadores de C estaban estancados en la convención anterior por necesidad de constantes como macros en mayúsculas, los programadores de C ++ eran más sensibles.

El gran problema hoy en día es cuando a las personas primero se les enseña Java, o C (con convenciones de la edad media) primero, y luego vienen a C ++, llevándose esa convención en mayúscula.

Entonces,

    int const answer = 42;    // Nice, good, OK.
    const int ANSWER = 0x2A;  // Ouch!
    #define COMPANYNAME_ANSWER 052  // Oh kill me, please.

Bueno, podrías haber pensado que mencioné los teclados solo en mayúsculas en broma. Oh no. Porque esa es simplemente la limitación de tecnología más antigua y arcaica que ha impulsado las convenciones de nomenclatura, o al menos ha afectado lo equivocado / correcto que parecían. Luego, surgió el problema de la transmisión en serie de 7 bits, que causó los problemas correspondientes con los códigos de caracteres (codificaciones de caracteres de newspeak) utilizados, lo que significaba que tenía que restringirse a las letras del alfabeto inglés, de la A a la Z.

En realidad, recomiendo seguir haciendo eso. Ahí es donde estamos! No hemos llegado más lejos.

En este momento, a partir de 2011, C ++ estándar admite nombres Unicode generales (y lo ha hecho desde 1998), mientras que las implementaciones reales de C ++ no. En particular, el compilador de g ++ tiene un carácter nacional cuestionado. Se deriva de esa limitación tecnológica de la edad oscura.

Entonces,

    double blueberryJamViscosity  = 0.0;    // OK
    double blåbærsyltetøyViskositet = 0.0;  // Ouch!

Finalmente, sobre el tema de guiones bajos versus letras mayúsculas intercaladas,

  • Reserve un formulario fácilmente reconocible para los nombres de tipo.
  • Reserve TODAS LAS MAYÚSCULAS para macros.
  • Se consistente.

Creo que es eso, en realidad, excepto por reglas como "generalmente evitar el nombre de una sola letra, excepto (loop, template param, blah blah)" y "evitar usar l, fácilmente confundido con 1" y "evitar O mayúscula, fácilmente confundido con 0 ". Además, por supuesto, evite usar nombres reservados como comenzar con un guión bajo seguido de mayúscula, que contiene dos guiones bajos sucesivos, o comenzar con un guión bajo y estar en el espacio de nombres global.

Saludos y hth

Alf P. Steinbach
fuente
Alf, ISTR Stroustrup menciona en D&E C copiar constdesde C ++, por lo que esto debe haber sucedido hace mucho tiempo, y mucho antes de Java, probablemente para C89.
sbi
2
Ah, y un sincero +1por "Sea coherente!" Al leerlo, me pregunto por qué olvidé mencionar esta regla, la más importante, en mi respuesta, cuando fue la que nunca olvidé decirles a mis alumnos. ¿Supongo que me perdonarás si ahora lo agrego a mi respuesta como una ocurrencia tardía?
sbi
2

Por lo general, tiendo a mantener la convención que más veo en las bases de código existentes para el lenguaje. En el caso de C ++, generalmente veo camelCase. En el caso de Ruby o PHP, generalmente veo stuff_like_this.

Sin embargo, en términos realistas, lo más importante es que elija una convención de estilo que no sea totalmente una locura (dOnT_dO_tHiS) y sea coherente con ella. Haz que el estilo no cambie a lo largo del código para un proyecto en particular. Si está trabajando en un proyecto existente, querrá seguir el estilo que ya existe.

DeM0nFiRe
fuente
1

Bueno, hay sistemas húngaros que es realmente común incluso ahora, pero prefiero cortarme la garganta que recomendarlo. Apps Hungarian es mejor, ya que sus marcas anotativas son realmente indicativas de semántica, aunque creo que es demasiado entusiasta con las abreviaturas cuando una palabra corta sería suficiente. (Para usar el ejemplo de esa página de Wikipedia, ¿ rwpor qué usar para fila cuando rowsolo tiene un carácter más? No es que haya una escasez global de vocales).

Sin embargo, de manera realista, lo más importante es seguir las convenciones de las personas con las que está trabajando . De Verdad. La mayoría de las convenciones funcionan lo suficientemente bien, especialmente si se usan de manera consistente. La inconsistencia es peor (incluso más que Systems Hungarian, que odio). Y si estás solo, usa lo que quieras.

Compañeros de Donal
fuente
1

Por lo que he visto, varía entre proyectos.

Los guiones bajos incrustados son probablemente más tradicionales / más utilizados en C en Unix. La biblioteca estándar también sigue esto, por lo que casi con certeza debería tratarse como predeterminado, a menos que haya suficiente código existente usando otra convención para forzar absolutamente el uso de esa otra convención.

Windows (por ejemplo) usa el caso camel para la mayoría de sus funciones, por lo que algunas personas que desarrollan para Windows hacen lo mismo. Esto también es bastante común entre las personas que están más acostumbradas a otros lenguajes e intentan tratar C ++ como si fuera una variante extraña de otra cosa.

Jerry Coffin
fuente
1

He usado tanto la biblioteca estándar como el boost como referencias para las convenciones de nomenclatura. Sin embargo, hay un problema con esta solución.

La biblioteca estándar utiliza una convención de nomenclatura diseñada para intentar reducir las colisiones con su código. Parte de la solución es usar todas las letras minúsculas. De ahí el uso de guiones bajos en lugar de camelCase.

Encuentro que camelCase es legible. PascalCase se usa a menudo para los nombres de clase, ya que representa el equivalente de un nombre propio. Sin embargo, romperé esa regla para los functores que son más representativos de un verbo.

Intento no usar macros. Sin embargo, cuando lo hago, las macros están hechas para parecerse a funciones cuando pueden. También uso valores constantes o enumeraciones en lugar de constantes manifiestas, evitando aún más todas las mayúsculas. Normalmente prefijo estos símbolos con una 'k' para indicar que son constantes.

// instead of a manifest constant
#define HOURS 24

// use const
const int kHours = 24; 

// or enum
enum {
    kHours   = 24,
    kMinutes = 60
};
Bill Door
fuente
0

Esta referencia describe una convención de nombres que es bastante similar a las que he visto utilizadas con éxito en al menos tres empresas para las que he trabajado en el pasado.

Contrariamente a una respuesta anterior, evitaría seguir la convención de nomenclatura de la Biblioteca estándar de C ++ en mi propio código, si no fuera por otra razón que evitar las colisiones de nombres con la Biblioteca estándar.

Esta respuesta SO anterior sobre un tema relacionado también puede ser de interés: /programming/228783/what-are-the-rules-about-using-an-underscore-in-ac-identifier

Gnawme
fuente
Umm, puede utilizar la misma convención de nombres sin utilizar los mismos nombres ... y si realmente desea que los mismos nombres, que está siendo protegido por espacios de nombres, por ejemplo std::stringvs gnawme::string.
einpoklum