你所不知道的 C 語言: 開發工具和規格標準

Copyright (慣C) 2015, 2017 宅色夫

==直播錄影==

Jonathan Adamczewski 貼出經典著作《The C Programming Language》,然後評註說:

"C++: The Good Parts"

C++ 可以美得令人不知所措 [source]

為什麼我不探討 C++

  • 在臺灣發文好像愛用「為什麼我不」開頭,後面可接「念研究所」、「待在大公司」等描述
  • C++ 自稱為物件導向的程式語言,卻不願意對物件在執行時期的表現負責任
    • 若說 C 語言給了你足夠的繩子吊死自己,那麼 C++ 給的繩子除了夠你上吊之外,還夠綁住你身邊的朋友
    • 相較之下,Java 讓你在吊死自己之際仍有親友監視著,雖然死不了,但事後會更想死
    • [ source ]
      • In Ruby, everything is an object.
      • In Clojure, everything is a list.
      • In Javascript, everything is a terrible mistake.
      • in C, everything is a representation (unsigned char [sizeof(TYPE)]).
  • Linus Torvalds 在 2010 年的解釋
  • C++ 實際上已經是截然不同的程式語言
  • 最重要的是,C++ 改版飛快,C++ 17 即將推出,但我還沒看懂 C++ 98

延伸閱讀


ISO/IEC 9899 (簡稱 "C99")

  • 一則笑話談起

    • "Programming in C: if it doesn't work, just add a star. Or multiple stars. Or ampersands."
  • 葉秉哲博士的推文:「==溯源能力==是很重要的,才不會被狀似革新,實則舊瓶裝新酒或跨領域借用的『新觀念』所迷惑」

  • 規格書 (PDF) 搜尋 "object",共出現 735 處

    • 搜尋 "pointer",共出現 637 處。有趣的是,許多教材往往不談 object,而是急著談論 pointer,殊不知,這兩者其實就是一體兩面
    • object != object-oriented
      • 前者的重點在於「資料表達法」,後者的重點在於 "everything is object"
    • C11 (ISO/IEC 9899:201x) / 網頁版
  • 從第一手資料學習:大文豪寫作都不免要查字典,庸俗的軟體開發者如我們,難道不需要翻閱語言規格書嗎?難道不需要搞懂術語定義和規範嗎?

  • & 不要都念成 and,涉及指標操作的時候,要讀為 "address of"

    • C99 標準 [6.5.3.2] Address and indirection operators 提到 '==&==' address-of operator
  • C99 [3.14] object

    • region of data storage in the execution environment, the contents of which can represent values

    • 在 C 語言的物件就指在執行時期,==資料==儲存的區域,可以明確表示數值的內容

    • 很多人誤認在 C 語言程式中,(int) 7 和 (float) 7.0 是等價的,其實以資料表示的角度來看,這兩者截然不同,前者對應到二進位的 "111",而後者以 IEEE 754 表示則大異於 "111"

    • A pointer to void shall have the same representation and alignment requirements as a pointer to a character type.

      關鍵描述!規範 void *char * 彼此可互換的表示法

void *memcpy(void *dest, const void *src, size_t n);
  • C99 規格書的解說就比很多書本清楚,何必捨近求遠呢?

    • EXAMPLE 1 The type designated as float * has type ""pointer to float’". Its type category is pointer, not a floating type. The const-qualified version of this type is designated as float - const whereas the type designated as "const float * is not a qualified type — its type is ""pointer to const qualified float’" and is a pointer to a qualified type.
    • EXAMPLE 2 The type designated as "struct tag (*[5])(float) has type "array of pointer to function returning struct tag’". The array has length five and the function has a single parameter of type float. Its type category is array.
  • Understand more about C 提及若干肇因於不同的 C 語言標準,而使得程式碼行為不同的案例

規格不能只看新的,過往也要熟悉

source

  • 空中巴士 330 客機的娛樂系統裡頭執行 14 年前的 Red Hat Linux,總有人要為「古董」負責
  • 而且空中巴士 380 客機也是如此

英文很重要

安裝 cdecl 程式,可以幫你產生 C 程式的宣告。

$ sudo apt-get install cdecl

使用案例

$ cdecl
cdecl> declare a as array of pointer to function returning pointer to function returning pointer to char

會得到以下輸出:

char *(*(*a[])())()

把前述 C99 規格的描述帶入,可得:

cdecl> declare array of pointer to function returning struct tag
struct tag (*var[])()

如果你沒辦法用英文來解說 C 程式的宣告,通常表示你不理解!

cdecl 可以解釋 C 程式宣告的意義,比方說:

cdecl> explain char *(*fptab[])(int)
declare fptab as array of pointer to function (int) returning pointer to char

GDB


除了 Vim,我推薦 Visual Studio Code


书籍推荐