예전과 같은 문자 사전 정의 (-ANSI 사전) unix
과 vax
코드가 컴파일되고 있던 어떤 시스템 컴파일시에 감지 할 수있는 방법이었다. 당시에는 공식 언어 표준이 없었으며 (K & R의 첫 번째 판 뒤에있는 참조 자료를 넘어서), 복잡한 C 코드는 일반적으로 #ifdef
시스템 간의 차이를 허용 하는 복잡한 미로였습니다 . 이러한 매크로 정의는 일반적으로 라이브러리 헤더 파일에 정의되지 않은 컴파일러 자체에 의해 설정됩니다. 구현에서 사용할 수있는 식별자와 프로그래머를 위해 예약 된 식별자에 대한 실제 규칙이 없었기 때문에 컴파일러 작성자는 간단한 이름을 자유롭게 사용 unix
하고 프로그래머가 자신의 목적으로 해당 이름을 사용하지 않는 것으로 가정했습니다.
1989 ANSI C 표준은 구현이 법적으로 사전 정의 할 수있는 기호를 제한하는 규칙을 도입했습니다. 컴파일러에 의해 미리 정의 된 매크로는 이름이 두 개의 밑줄로 시작하거나 밑줄과 대문자로 시작하므로 프로그래머는 해당 패턴과 일치하지 않고 표준 라이브러리에서 사용되지 않는 식별자를 자유롭게 사용할 수 있습니다.
결과적으로, 사전 정의 unix
되거나 linux
부적합한 컴파일러 는와 같은 것을 사용하는 완벽하게 유효한 코드를 컴파일하지 못하기 때문에 int linux = 5;
.
이와 같이 gcc는 기본적으로 부적합하지만 올바른 명령 행 옵션을 사용하여 (합리적으로 잘) 만들 수 있습니다.
gcc -std=c90 -pedantic ... # or -std=c89 or -ansi
gcc -std=c99 -pedantic
gcc -std=c11 -pedantic
자세한 내용 은 gcc 설명서 를 참조하십시오.
gcc는 다음 릴리스에서 이러한 정의를 단계적으로 폐지 할 것이므로이 정의에 의존하는 코드를 작성해서는 안됩니다. 프로그램이 Linux 대상 용으로 컴파일되는지 여부를 알아야하는 경우 __linux__
gcc 또는 호환되는 컴파일러를 사용한다고 가정하여 정의되어 있는지 확인할 수 있습니다 . 자세한 내용 은 GNU C 전 처리기 설명서 를 참조하십시오.
David Korn (예, Korn Shell의 저자)이 1987 년 국제 난독 화 C 코드 경연 대회 에서 "최고의 라이너"를 획득 한 경우 미리 정의 된 unix
매크로를 활용했습니다 .
main() { printf(&unix["\021%six\012\0"],(unix)["have"]+"fun"-0x60);}
"unix"
매크로 이름의 철자와는 전혀 관련이없는 이유로 인쇄합니다 .