Nos velhos tempos (pré-ANSI), predefinir símbolos como unix
e vax
era uma maneira de permitir que o código detectasse em tempo de compilação em que sistema estava sendo compilado. Não havia um padrão de idioma oficial na época (além do material de referência no final da primeira edição da K&R), e o código C de qualquer complexidade era tipicamente um labirinto complexo de #ifdef
s para permitir diferenças entre os sistemas. Essas definições de macro geralmente eram definidas pelo próprio compilador, não definidas em um arquivo de cabeçalho da biblioteca. Como não havia regras reais sobre quais identificadores poderiam ser usados pela implementação e quais eram reservados para programadores, os criadores de compiladores sentiram-se à vontade para usar nomes simples como unix
e assumiram que os programadores simplesmente evitariam usar esses nomes para seus próprios fins.
O padrão ANSI C de 1989 introduziu regras que restringem quais símbolos uma implementação pode legalmente predefinir. Uma macro predefinida pelo compilador só pode ter um nome que comece com dois sublinhados ou com um sublinhado seguido de uma letra maiúscula, deixando os programadores livres para usar identificadores que não correspondem ao padrão e não são usados na biblioteca padrão.
Como resultado, qualquer compilador que predefinir unix
ou linux
não estiver em conformidade, pois ele falhará ao compilar um código perfeitamente legal que use algo parecido int linux = 5;
.
Por acaso, o gcc não está em conformidade por padrão - mas pode ser feito para estar em conformidade (razoavelmente bem) com as opções corretas da linha de comando:
gcc -std=c90 -pedantic ... # or -std=c89 or -ansi
gcc -std=c99 -pedantic
gcc -std=c11 -pedantic
Veja o manual do gcc para mais detalhes.
O gcc eliminará essas definições em versões futuras, portanto você não deve escrever código que dependa delas. Se o seu programa precisa saber se está sendo compilado para um destino Linux ou não, pode verificar se __linux__
está definido (supondo que você esteja usando o gcc ou um compilador compatível com ele). Veja o manual do pré-processador GNU C para mais informações.
Um aspecto amplamente irrelevante: o vencedor do "Best One Liner" do Concurso Internacional de Código C Ofuscado de 1987 , de David Korn (sim, o autor do Korn Shell) aproveitou a unix
macro predefinida :
main() { printf(&unix["\021%six\012\0"],(unix)["have"]+"fun"-0x60);}
Ele é impresso "unix"
, mas por motivos que não têm absolutamente nada a ver com a ortografia do nome da macro.