《C专家编程》一1.11 轻松一下——由编译器定义的Pragmas效果

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”的次序搞反了。

[1] 学习、使用和实现PL/I的困难使一位程序员写了这样一首打油诗:“IBM有个PL/I,语法比JOSS还糟糕,到处都见它踪影,实实在在是垃圾。JOSS是个老古董,它可不是因简单而闻名。”

[2]  “BCPL:A Tool for Compiler Writing and System Programming(BCPL,编译器编写和系统编程的工具),” Martin Richards, Proc. AFIPS Spring Joint Computer Conference, 34(1969), pp.557-566。BCPL并非“Before C Programming Language(C前身编程语言)”的首字母缩写,尽管这是个有趣的巧合。它的确切意思是“Basic Combined Programming Language(基本组合编程语言)”。basic的意思是“不花哨”,它是由英国伦敦大学和剑桥大学的研究人员合作开发的。Multics实现了一种BCPL编译器。

[3] 本书原版出于1994年,当时距1970年还不到30年。——译者注

[4] ANSI C Rationale(单独)可通过匿名FTP,从ftp.uu.net下载,位于/doc/standards/ansi/X3.159-1989/(如果你不明白匿名FTP,赶紧到附近的书店买一本关于Internet的书,免得成为信息高速公路上的“跛行的羔羊”)。Rationale的纸版书也已出版,ANSI C Rationale, 新泽西Silicon Press,1990。ANSI C标准本身无法从任何ftp站点下载,因为标准印刷本的营业收入是ANSI的重要收入来源之一。

[5] 如果你想刨根问底,它位于第5.1.1.3段,“Diagnostics(诊断)”。作为一个语言标准,它不会简单地说“在一个不正确的程序里,你必须为每个错误准备一个标志”。作为标准,其用辞必然骈四骊六,仿佛是由靠玩弄文字吃饭的律师所撰写的。它的正式用辞如下:“一个遵循标准的实现应该*至少为每个翻译单元产生一条诊断信息,其中包含了所有违反语法规则或约束的行为。在其他情况下不必产生诊断信息”。
*Brian Scearce+ 所总结的有用规律——如果你听到一个程序员说“应该(shall)”,那么他一定在引用标准里的说法。
+嵌套脚注(nested footnote)的发明者。

[6] The New Hacker's Dictionary把语言律师定义为“能从200多页的手册中提取5句话,拼起来放到你面前,你只要一看就能明白自己问题的答案的人”,嘿!在这个例子的情况下正是如此。

[7] 即int是32位。——译者注

[8] 即long 是32位而int是16位。——译者注

[9] 即long和int均为32位。——译者注

[10] The Elements of Programming Style, Kernighan(对,就是那个Kernighan)和Plauger,纽约,McGraw Hill,1978。这是一本文字流畅、细节真实的优秀作品——非常值得购买,你能从中获益良多。

时间: 2024-10-22 03:09:15

《C专家编程》一1.11 轻松一下——由编译器定义的Pragmas效果的相关文章

《C专家编程》一导读

前 言 C专家编程 C代码.C代码运行.运行码运行-请! --Barbara Ling 所有的C程序都做同一件事,观察一个字符,然后啥也不干. --Peter Weinberger 你是否注意到市面上存有大量的C语言编程书籍,它们的书名具有一定的启示性,如:C Traps and Pitfalls(本书中文版<C陷阱与缺陷>已由人民邮电出版社出版), The C Puzzle Book, Obfuscated C and Other Mysteries,而其他的编程语言好像没有这类书.这里有一

《JavaScript专家编程》——第9章 代码质量 9.1 定义代码质量

第9章 代码质量 质量不是一种行为,而是一种习惯. --Aristotle 写高质量的JavaScript是什么意思?质量能度量吗?还是说它是一个主观感受,类似于美和艺术的柏拉图式的理想?程序员往往会在质量的主观和客观理解之间摇摆不定.他们提出了诸如软件工艺的概念,这是一种用类似手工艺的方法来编写软件的方式.软件工匠常被这样描述:他们拥有超群的技术,总是能将工作提炼为基本的.本质的部件.这样一个工匠在电气上被称为摇滚明星程序员.这基于两个标准,一是这个人具有如同艺术家一样的独特天赋,二是他工作的

《C专家编程》一1.8 ANSI C标准的结构

1.8 ANSI C标准的结构 如果我们岔开话题,快速浏览一下ANSI C标准的出处和内容,对读者应该是有帮助的.ANSI C标准分成四个主要的部分: 第4节:介绍(共5页).对术语进行介绍和定义. 第5节:环境(共13页).描述了围绕和支持C语言的系统,包括在程序启动时发生什么,程序中止时发生什么,以及一些信号和浮点数运算.编译器的最低限制和字符集信息也在这一部分介绍. 第6节:C语言(共78页).标准的这部分是基于Dennis Ritchie数次出版的经典之作"The C Reference

Android编程实现带有图标的ListView并带有长按菜单效果示例

本文实例讲述了Android编程实现带有图标的ListView并带有长按菜单效果.分享给大家供大家参考,具体如下: MainActivity.Java package com.zxl; import java.util.ArrayList; import java.util.List; import org.w3c.dom.ls.LSException; import android.app.Activity; import android.os.Bundle; import android.v

《JavaScript专家编程》——9.4 度量JavaScript代码质量

9.4 度量JavaScript代码质量 为了让计算精度上升到最高,客观质量分析以程序化的方式对代码进行分析.这项任务可以使用编程工具完成,这些工具能够在多种情况下评估代码,根据各项指标得到最终的质量得分.本节介绍了静态代码分析,这种方法非常适合评估JavaScript的质量. 静态代码分析 静态代码分析就是不通过运行代码来分析代码的过程.静态分析看起来非常像一个文本编辑器的拼写检查器.拼写检查器扫描文档的正文来寻找错误和含糊之处,而并不需要了解文本的意义.同时,静态代码分析从功能上分析源代码的

《圣殿祭司的ASP.NET4.0专家技术手册》----1-1 ASP.NET平台的三分天下

1-1 ASP.NET平台的三分天下 圣殿祭司的ASP.NET4.0专家技术手册 如果访问微软www.asp.net网站,会发现ASP.NET技术目前有3位成员:Web Form.MVC和Web Pages,如图1-1所示.它们各有不同的定位与特色,彼此的开发方式也不相同.目前,使用人数与市场占有率最高的仍是Web Form,而MVC近两年有不少技术玩家和项目采用,至于Web Pages,则是另外的Web Matrix开发工具预定的网页开发技术,它走更易于使用的开发路线. 你心里可能有疑问:"为

高质量C++/C编程指南-第11章-其它编程经验(2)

11.1.3 const成员函数 任何不会修改数据成员的函数都应该声明为const类型.如果在编写const成员函数时,不慎修改了数据成员,或者调用了其它非const成员函数,编译器将指出错误,这无疑会提高程序的健壮性. 以下程序中,类stack的成员函数GetCount仅用于计数,从逻辑上讲GetCount应当为const函数.编译器将指出GetCount函数中的错误. class Stack { public: void Push(int elem); int Pop(void); int

关于提高编程技能的11大秘籍

我们开门见山地说吧: 1.首先仔细分析问题 2.接着好好想想如何解决这个问题 3.收集整理所有需求. 花点时间将最终产品要实现的目标写下来,并且明确哪些是我们的目标用户群.如果这一步能做好的话,将会给后面节约大量的时间,正所谓磨刀不误砍柴工. 4.写一个全面的实施计划(或模型). 如果是个小项目,这一步出来的可能只是一个基本的流程或者一个简单的等式. 如果是个比较大的项目,这一步有助于我们将它切割成几个模块,然后再按下面的问题思考: 各个模块需要执行什么任务 模块之间如何传递数据 如何调用模块中

《JavaScript专家编程》——1.2 对象概述

1.2 对象概述 JavaScript是由Brendan Eich创建的一种面向对象编程(OOP)语言,当时他还在Netscape公司工作,花了几周的开发时间就发布了.虽然JavaScript的名字中有个"Java",但它实际上跟Java语言没什么关系.在InfoWorld的一篇对Eich的采访稿中,他解释了JavaScript命名的由来: InfoWorld:据我所知,JavaScript开始的时候叫Mocha,后来改名叫LiveScript,在 Netscape和Sun合并以后才叫