Para C, a primeira edição da The C Programming Language (aka K&R) sugere que sua intuição sobre macros de pré-processador está correta:
Os nomes de constantes simbólicos são geralmente escritos em maiúsculas, para que possam ser facilmente distinguidos dos nomes de variáveis em minúsculas.
De muitas maneiras, essa era uma retração da linguagem assembly, onde as macros eram definidas em maiúsculas, juntamente com rótulos, códigos de operação, nomes de registro e tudo mais. O advento da montagem no estilo AT&T mudou isso em algumas plataformas, mas acho que foi fortemente influenciado pelo fato de os terminais que suportam letras minúsculas estavam se tornando uma coisa e o Unix era o que eu chamaria de "sistema operacional minúsculo".
Nos outros dois pontos, você está batendo .500:
Enum
No momento em que a segunda edição foi publicada, enum
já havia sido definido, eles eram referidos como constantes de enumeração e abordados na seção sobre constantes. Como as constantes definidas por um enum
são representadas por símbolos, isso as torna constantes simbólicas que, se você seguir a convenção recomendada, devem ser nomeadas em maiúsculas. (Como macros de pré-processador, nada impede você de fazer o contrário.)
A implicação aqui é que, diferentemente de alguns idiomas que se seguiram, C não trata enum
como um tipo de primeira classe em que os tipos são distintos, os valores de enumeração são específicos para cada tipo e podem ser reutilizados em outros. Em vez disso, é efetivamente uma abreviação conveniente para #define
que produz seqüências de números inteiros com identificadores anexados. Isto faz
enum foo { BAR, BAZ };
enum quux { BLETCH, BAZ };
inválido porque todos os símbolos compartilham escopo e BAZ
são redefinidos. (Essa foi uma melhoria em relação ao pré-processador que, na época, não avisava sobre um #define
bater no outro.) Além disso, C não se importa se você os mistura porque todos são apenas números inteiros, tornando
enum foo { BAR, BAZ };
enum quux { BLETCH, BLRFL };
enum foo variable = BLETCH;
completamente válido mesmo em um compilador moderno com todos os avisos ativados.
Const
NB: A const
palavra-chave se originou em 1981 com C With Classes do Stroustrup (que evoluiu para C ++) e foi finalmente adotada por C. A escolha do nome é lamentável, porque colide com o uso do termo constante por K&R para significar o que chamaríamos agora de literal (por exemplo, 38
, 'x'
ou "squabble"
). O texto da segunda edição não foi reescrito para refletir isso.
As variáveis declaradas const
são uma história diferente porque ainda são variáveis. Eles não devem ser modificados, mas se a noção de uma variável constante faz mais sentido do que, digamos, camarão jumbo é forragem para outra discussão. Seja qual for o caso, C nunca foi realmente sério sobre isso, porque o padrão requer apenas que o compilador emita um diagnóstico quando você tenta alterar um. O comportamento real é indefinido se uma modificação for compilada e executada.
Sendo variáveis, faz sentido que qualquer coisa const
siga a convenção de ser nomeado em minúsculas. Usá-los para representar literais tem algumas vantagens de segurança de tipo, mas não é uma boa otimização se você precisar alcançar entre unidades de compilação para obter o valor.
O que eles não são são constantes no sentido de K&R e, por esse motivo, seus identificadores não devem estar em maiúsculas. Algumas pessoas as usam dessa maneira, mas não é uma prática que eu recomendo, exceto em alguns casos específicos.
const
identificadores em minúsculas e#defines
maiúsculas. O Java adotou letras maiúsculas para constantes e outras linguagens, mas eu poderia estar errado com esse último bit. É necessária mais pesquisa! :)