Para C, la primera edición de The C Programming Language (también conocido como K&R) sugiere que su intuición sobre las macros de preprocesadores es correcta:
Los nombres constantes simbólicos se escriben comúnmente en mayúsculas para que puedan distinguirse fácilmente de los nombres de variables en minúsculas.
En muchos sentidos, esto era un remanente del lenguaje ensamblador, donde las macros se definían en mayúsculas junto con etiquetas, códigos de operación, nombres de registro y todo lo demás. El advenimiento del ensamblaje de estilo AT&T cambió eso en algunas plataformas, pero creo que estuvo muy influenciado por el hecho de que los terminales que admiten minúsculas se estaban convirtiendo en algo y Unix era lo que yo llamaría un "sistema operativo en minúsculas".
En los otros dos puntos, estás bateando .500:
Enum
Para cuando se publicó la segunda edición, enum
habían definido los correos electrónicos, se los denominaba constantes de enumeración y se los cubría en la sección de constantes. Debido a que las constantes definidas por un enum
están representadas por símbolos, eso las convierte en constantes simbólicas que, si va a seguir la convención recomendada, deben nombrarse en mayúsculas. (Al igual que las macros de preprocesador, nada le impide hacer lo contrario).
La implicación aquí es que, a diferencia de algunos lenguajes que siguieron, C no trata enum
como un tipo de primera clase donde los tipos en sí son distintos, los valores de enumeración son específicos de cada tipo y pueden reutilizarse en otros. En cambio, es efectivamente una forma abreviada conveniente para #define
que produce secuencias de enteros con identificadores adjuntos. Esto hace
enum foo { BAR, BAZ };
enum quux { BLETCH, BAZ };
inválido porque todos los símbolos comparten alcance y BAZ
se redefinen. (Esta fue una mejora sobre el preprocesador que, en ese momento, no advirtió sobre uno#define
golpeteo sobre otro.) Además, a C no le importa si los mezclas porque son todos enteros, haciendo
enum foo { BAR, BAZ };
enum quux { BLETCH, BLRFL };
enum foo variable = BLETCH;
completamente válido incluso en un compilador moderno con todas las advertencias activadas.
Const
NB: La const
palabra clave se originó en 1981 con C With Classes de Stroustrup (que evolucionó a C ++) y finalmente fue adoptada por C. La elección del nombre es desafortunada, porque colisiona con el uso de K&R del término constante para significar lo que ahora llamaríamos un literal (por ejemplo 38
, 'x'
o"squabble"
). El texto en la segunda edición no fue reescrito para reflejar eso.
Variables declaradas const
son una historia diferente porque siguen siendo variables. Se supone que no deben modificarse, pero si la noción de una variable constante tiene más sentido que, digamos, el camarón gigante es el forraje para otra discusión. En cualquier caso, C nunca fue realmente serio al respecto porque el estándar solo requiere que el compilador emita un diagnóstico cuando intente cambiar uno. El comportamiento real no está definido si se compila y ejecuta una modificación.
Al ser variables, tiene sentido que cualquier cosa const
siga la convención de ser nombrado en minúsculas. Usarlos para representar literales tiene algunas ventajas de seguridad de tipo, pero no es una buena optimización si tiene que alcanzar entre unidades de compilación para obtener el valor.
Lo que no son son constantes en el sentido de K&R, y por esa razón sus identificadores no deberían estar en mayúsculas. Algunas personas los usan de esa manera, pero no es una práctica que recomiendo, excepto en algunos casos específicos.
const
identificadores en minúsculas y#defines
en mayúsculas. Sin embargo, Java adoptó mayúsculas para constantes y otros lenguajes seguidos, pero podría equivocarme un poco. ¡Se necesita más investigación! :)