栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

为什么C预处理程序将单词“ linux”解释为常量“ 1”?

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

为什么C预处理程序将单词“ linux”解释为常量“ 1”?

在过去(ANSI之前的版本)中,预定义符号(例如

unix
和)
vax
是一种允许代码在编译时检测其针对哪个系统进行编译的方法。当时没有正式的语言标准(除了K&R第一版后面的参考资料之外),任何复杂的C代码通常都是
#ifdef
s
的复杂迷宫,以允许系统之间的差异。这些宏定义通常由编译器本身设置,而不是在库头文件中定义。由于对于实现可以使用哪些标识符以及哪些标识符保留给程序员没有真正的规则,因此编译器作者可以随意使用简单的名称,例如,
unix
并假定程序员会简单地避免出于自己的目的使用这些名称。

1989年的ANSI
C标准引入了一些规则,这些规则限制了实现可以合法定义的符号。编译器预定义的宏只能使用以两个下划线开头的名称,或者以下划线后接大写字母的名称,从而使程序员可以自由使用与该模式不匹配且未在标准库中使用的标识符。

结果,任何预定义

unix
linux
不合格的编译器都将无法编译完全合法的代码,例如
int linux = 5;

碰巧的是,gcc默认情况下是不符合标准的-但可以使其与正确的命令行选项相符合(合理):

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

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

gcc将在将来的版本中逐步淘汰这些定义,因此您不应编写依赖它们的代码。如果您的程序需要知道它是否正在针对Linux目标进行编译,则可以检查是否

__linux__
已定义(假设您使用的是gcc或与其兼容的编译器)。有关更多信息,请参见GNU
C预处理程序手册

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

unix
宏:

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

它打印

"unix"
,但是由于与宏名称的拼写绝对无关的原因。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/405564.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号