Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
471 views
in Technique[技术] by (71.8m points)

c - 为什么C预处理程序将单词“ linux”解释为常量“ 1”?(Why does the C preprocessor interpret the word “linux” as the constant “1”?)

Why does the C preprocessor in GCC interpret the word linux (small letters) as the constant 1 ?

(为什么GCC中的C预处理器将linux (小写字母)一词解释为常量1 ?)

test.c:

(test.c的:)

#include <stdio.h>
int main(void)
{       
    int linux = 5;
    return 0;
}

Result of $ gcc -E test.c (stop after the preprocessing stage):

($ gcc -E test.c结果(在预处理阶段之后停止):)

....
int main(void)
{
    int 1 = 5;
    return 0;
}

Which -of course- yields an error.

(当然,这会产生错误。)

(BTW: There is no #define linux in the stdio.h file.)

((顺便说一句:stdio.h文件中没有#define linux 。))

  ask by ahmedaly50 translate from so

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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.

(在旧时代(pre-ANSI)中,预定义符号(例如unixvax是一种允许代码在编译时检测其针对哪个系统进行编译的方法。)

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.

(当时没有正式的语言标准(除了K&R第一版后面的参考资料之外),任何复杂的C代码通常都是#ifdef的复杂迷宫,以允许系统之间存在差异。)

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.

(由于对于实现中可以使用哪些标识符以及哪些标识符保留给程序员没有真正的规则,因此编译器编写者可以随意使用诸如unix类的简单名称,并假定程序员会简单地避免将这些名称用于自己的目的。)

The 1989 ANSI C standard introduced rules restricting what symbols an implementation could legally predefine.

(1989年的ANSI C标准引入了一些规则,这些规则限制了实现可以合法定义的符号。)

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.

(编译器预定义的宏只能使用以两个下划线开头的名称,或者以下划线后接大写字母的名称,从而使程序员可以自由使用与该模式不匹配且未在标准库中使用的标识符。)

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;

(结果,任何预定义unixlinux编译器都是不合格的,因为它将无法完全编译使用int linux = 5;类的合法代码int linux = 5;)

.

(。)

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默认情况下是不符合标准的-但可以使其与正确的命令行选项相符合(合理):)

gcc -std=c90 -pedantic ... # or -std=c89 or -ansi
gcc -std=c99 -pedantic
gcc -std=c11 -pedantic

See the gcc manual for more details.

(有关更多详细信息,请参见gcc手册 。)

gcc will be phasing out these definitions in future releases, so you shouldn't write code that depends on them.

(gcc将在将来的版本中逐步淘汰这些定义,因此您不应编写依赖它们的代码。)

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).

(如果您的程序需要知道是否正在针对Linux目标进行编译,则可以检查是否已定义__linux__ (假设您使用的是gcc或与其兼容的编译器)。)

See the GNU C preprocessor manual for more information.

(有关更多信息,请参见GNU C预处理程序手册 。)

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:

(很大程度上无关紧要的是:David Korn(是,Korn Shell的作者)在1987年国际混淆式C代码竞赛中获得“最佳一线”奖,它利用了预定义的unix宏:)

main() { printf(&unix["21%six12"],(unix)["have"]+"fun"-0x60);}

It prints "unix" , but for reasons that have absolutely nothing to do with the spelling of the macro name.

(它输出"unix" ,但是由于与宏名称的拼写完全无关的原因。)


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...