1.11 轻松一下——由编译器定义的Pragmas效果 自由软件基金会(Free Software Foundation)是一个独特的组织,它由MIT顶级黑客Richard Stallman所创立。顺便提一下,我们所说的“黑客”,它的原先意思是“天才程序员”。后来这个称呼被媒体所贬损,致使它在局外人眼中成了“邪恶的天才”的代名词。和形容词“bad”一样,“黑客”现在也有两个相反的意思,必须通过上下文才能明白它的确切意思。
Stallman成立自由软件基金会的初衷是:软件应该是免费的,所有人都可以自由使用。FSF的宗旨是“消除在计算机程序拷贝、重发布、理解和修改方面的限制”,它雄心勃勃地想建立一个UNIX的自由软件实现方案,称为GNU(它代表“GNU’s Not UNIX”,对,确实如此)。
许多计算机科学研究生和其他人赞同GNU的哲学,他们设计软件产品,由FSF进行打包并免费发布。通过这些甘心奉献的有天赋的程序员们的辛勤劳动,产生了一些优秀的软件作品。FSF最好的作品之一就是GNU C编译器系列。gcc是一个健壮的、在代码优化方面具有创造性的编译器,可以在很多硬件平台使用,有时甚至比编译器厂商的产品更为优秀。gcc并不适合所有的项目,它在维护性和未来版本连续性方面仍存在一些问题。在现实的开发中,除了编译器之外,还需要很多工具。曾有很长一段时间,GNU的调试器无法在共享库中工作。而且在开发时,GNU C偶尔会让人感到眼花缭乱。
在制订ANSI C标准时,引入了pragma指示符,这个指示符来源于Ada。#pragma用于向编译器提示一些信息,诸如希望把某个特定函数扩展为内联函数,或者取消边界的检查。由于它并非C语言所固有,pragma遭到了一个gcc编译器设计者的积极抵制,他把这个“由编译器定义的”的效果做得很搞笑—在gcc 1.34版,如果使用了pragma,将会导致编译器停止编译,而是运行一个计算机游戏!在gcc手册中有如下说明:
在ANSI C标准中,“#pragma”指令会产生一个由编译器定义的任意效果。在GNU C预处理器中,一旦遇见“#pragma”指令,它首先试图运行“rogue”游戏;如果失败,尝试运行“hack”游戏;如果还是失败,它会尝试运行GNU Emacs,显示汉诺塔(Tower of Hanoi)。如果仍然失败,它就报告一个致命错误。总之,预处理过程不会继续下去。
—— GNU C编译器1.34版手册
GNU C编译器中关于预处理器的那部分源代码如下:
/ *
* #pragma指示符的行为是由编译器定义的。
* 在GNU C编译器中,它的定义如下:
* /
do_pragma()
{
close(0);
if(open("/dev/tty", O_RDONLY, 0666) != 0)
goto nope;
close(1);
if(open("/dev/tty", O_WRONLY, 0666) != 1)
goto nope;
exel("/usr/games/hack", "#pragma", 0);
exel("/usr/games/rogue", "#pragma", 0);
exel("/usr/new/emacs", "-f", "hanoi", "9", "-kill", 0);
exel("/usr/local/emacs", "-f", "hanoi", "9", "-kill", 0);
nope:
fatal("you are in a maze of twisty compiler features, all different");
}
特别好笑的是,用户手册中的描述是错误的,它把“hack”和“rogue”的次序搞反了。
|