天天看點

《C專家程式設計》一1.11 輕松一下——由編譯器定義的Pragmas效果

本節書摘來自異步社群《c專家程式設計》一書中的第1章,第1.11節,作者 【美】perter van der linde,更多章節内容可以通路雲栖社群“異步社群”公衆号檢視

自由軟體基金會(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編譯器中關于預處理器的那部分源代碼如下:

特别好笑的是,使用者手冊中的描述是錯誤的,它把“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。這是一本文字流暢、細節真實的優秀作品——非常值得購買,你能從中獲益良多。

繼續閱讀