En los viejos tiempos (pre-ANSI), predefinir símbolos como unix
y vax
era una forma de permitir que el código detectara en el momento de la compilación para qué sistema se estaba compilando. No existía un estándar de idioma oficial en ese entonces (más allá del material de referencia en la parte posterior de la primera edición de K&R), y el código C de cualquier complejidad era típicamente un complejo laberinto de #ifdef
s para permitir diferencias entre sistemas. Estas definiciones de macro generalmente fueron establecidas por el compilador, no definido en un archivo de encabezado de biblioteca. Dado que no había reglas reales sobre qué identificadores podrían ser utilizados por la implementación y cuáles estaban reservados para los programadores, los escritores de compiladores se sintieron libres de usar nombres simples como unix
y asumieron que los programadores simplemente evitarían usar esos nombres para sus propios fines.
El estándar ANSI C de 1989 introdujo reglas que restringen los símbolos que una implementación podría predefinir legalmente. Una macro predefinida por el compilador solo podría tener un nombre que comience con dos guiones bajos, o con un guión bajo seguido de una letra mayúscula, dejando a los programadores libres de usar identificadores que no coincidan con ese patrón y que no se usen en la biblioteca estándar.
Como resultado, cualquier compilador que predefine unix
o linux
no sea conforme, ya que no podrá compilar código perfectamente legal que use algo así int linux = 5;
.
De hecho, gcc no es conforme de forma predeterminada, pero se puede hacer que se ajuste (razonablemente bien) con las opciones de línea de comandos correctas:
gcc -std=c90 -pedantic ... # or -std=c89 or -ansi
gcc -std=c99 -pedantic
gcc -std=c11 -pedantic
Consulte el manual de gcc para más detalles.
gcc eliminará estas definiciones en futuras versiones, por lo que no debe escribir código que dependa de ellas. Si su programa necesita saber si se está compilando para un objetivo de Linux o no, puede verificar si __linux__
está definido (suponiendo que esté usando gcc o un compilador que sea compatible con él). Consulte el manual del preprocesador GNU C para obtener más información.
Un aparte en gran medida irrelevante: el ganador del "Mejor trazador de líneas" del Concurso Internacional de Código C Ofuscado de 1987 , por David Korn (sí, el autor del Korn Shell) se aprovechó de la unix
macro predefinida :
main() { printf(&unix["\021%six\012\0"],(unix)["have"]+"fun"-0x60);}
Imprime "unix"
, pero por razones que no tienen absolutamente nada que ver con la ortografía del nombre de la macro.