七度&光 2013-10-06 16:09 采纳率: 22.2%
浏览 312
已采纳

为什么 c 预处理器将"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;
}

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

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

转载于:https://stackoverflow.com/questions/19210935/why-does-the-c-preprocessor-interpret-the-word-linux-as-the-constant-1

  • 写回答

5条回答 默认 最新

  • 叼花硬汉 2013-10-06 21:11
    关注

    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 #ifdefs 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.

    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.

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

    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
    

    See the gcc manual for more details.

    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.

    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);}
    

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

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(4条)

报告相同问题?

悬赏问题

  • ¥60 pb数据库修改或者求完整pb库存系统,需为pb自带数据库
  • ¥15 spss统计中二分类变量和有序变量的相关性分析可以用kendall相关分析吗?
  • ¥15 拟通过pc下指令到安卓系统,如果追求响应速度,尽可能无延迟,是不是用安卓模拟器会优于实体的安卓手机?如果是,可以快多少毫秒?
  • ¥20 神经网络Sequential name=sequential, built=False
  • ¥16 Qphython 用xlrd读取excel报错
  • ¥15 单片机学习顺序问题!!
  • ¥15 ikuai客户端多拨vpn,重启总是有个别重拨不上
  • ¥20 关于#anlogic#sdram#的问题,如何解决?(关键词-performance)
  • ¥15 相敏解调 matlab
  • ¥15 求lingo代码和思路