问题描述
为什么在GCC间preT字的C preprocessor 的Linux
(小写字母)作为恒 1
?
Why does the C preprocessor in GCC interpret the word linux
(small letters) as the constant 1
?
test.c的:
#include <stdio.h>
int main(void)
{
int linux = 5;
return 0;
}
$ gcc的-E test.c以
的结果(preprocessing阶段结束后停止):
Result of $ gcc -E test.c
(stop after the preprocessing stage):
....
int main(void)
{
int 1 = 5;
return 0;
}
这-OF课程 - 产生错误。
Which -of course- yields an error.
(顺便说一句:没有 linux下的#define
中的文件stdio.h中)
(BTW: There is no #define linux
in the stdio.h file.)
推荐答案
在过去(pre-ANSI),predefining符号,如 UNIX
和 VAX
是一个办法,让code到什么系统它被编译为编译时检测。有没有官方语言标准的当年(超出参考材料在K&放第一版的背面; R),以及任何复杂的C code为一般的#IFDEF s到允许系统之间的差异。这些宏定义一般是由编译器本身,在库的头文件中定义设置。由于大约有哪些标识符可以由执行使用,这都留给了程序员没有真正的规则,编译器的作者感到自由使用简单的名称,如
UNIX
并假设程序员会简单地避免使用为自己的目的的名字。
In the Old Days (pre-ANSI), predefining symbols such as unix
and vax
was a way to allow code to detect at compile time what system it was being compiled for. There was no official language standard back then (beyond the reference material at the back of the first edition of K&R), and C code of any complexity was typically a complex maze of #ifdef
s to allow for differences between systems. These macro definitions were generally set by the compiler itself, not defined in a library header file. Since there were no real rules about which identifiers could be used by the implementation and which were reserved for programmers, compiler writers felt free to use simple names like unix
and assumed that programmers would simply avoid using those names for their own purposes.
1989年的ANSI C标准中引入的规则限制什么符号可以合法predefine的实现。由编译器pdefined宏$ P $只能有一个名称开头的两个下划线,或以下划线后跟一个大写字母,让程序员可以自由使用标识符不匹配的模式和标准库不能使用。
The 1989 ANSI C standard introduced rules restricting what symbols an implementation could legally predefine. A macro predefined by the compiler could only have a name starting with two underscores, or with an underscore followed by an uppercase letter, leaving programmers free to use identifiers not matching that pattern and not used in the standard library.
作为结果,predefines任何编译器 UNIX
或的Linux
是不合格的,因为它将无法编译使用类似 INT完全合法code的Linux = 5;
As a result, any compiler that predefines unix
or linux
is non-conforming, since it will fail to compile perfectly legal code that uses something like int linux = 5;
.
碰巧的是,GCC是不符合默认情况下 - 但它可以制成符合(相当不错)用正确的命令行选项:
As it happens, gcc is non-conforming by default -- but it can be made to conform (reasonably well) with the right command-line options:
gcc -std=c90 -pedantic ... # or -std=c89 or -ansi
gcc -std=c99 -pedantic
gcc -std=c11 -pedantic
请参阅了解更多详情。
GCC将被逐步淘汰在未来的版本中这些定义,所以你不应该写code这取决于他们。如果你的程序需要知道是否它正在编译Linux目标或没有它可以检查是否 __的Linux __
定义(假设你使用gcc或编译器与它兼容)。请参见了解详情。
gcc will be phasing out these definitions in future releases, so you shouldn't write code that depends on them. If your program needs to know whether it's being compiled for a Linux target or not it can check whether __linux__
is defined (assuming you're using gcc or a compiler that's compatible with it). See the GNU C preprocessor manual for more information.
一个基本上是无能为力的旁白:1987年的最佳单行获得者,由大卫科恩(是的,在Korn shell的作者)把pdefined的$ p $的优势 UNIX
宏:
A largely irrelevant aside: the "Best One Liner" winner of the 1987 International Obfuscated C Code Contest, by David Korn (yes, the author of the Korn Shell) took advantage of the predefined unix
macro:
main() { printf(&unix["\021%six\012\0"],(unix)["have"]+"fun"-0x60);}
它打印UNIX
,但有绝对无关,与宏名的拼写原因。
It prints "unix"
, but for reasons that have absolutely nothing to do with the spelling of the macro name.
这篇关于为什么的C preprocessor间preT词QUOT; Linux和QUOT;作为常数QUOT; 1 QUOT ;?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!