為什麼 Linux 內核中不經常使用 typedef?

在使用C語言編寫程序時,我們看見很多都對結構體使用了typedef,在stackoverflow上這個問題Why should we typedef a struct so often in C?就討論了這樣的使用帶來的好處,但是為什麼在Linux 內核中像task_struct,mm_struct這樣的數據結構確沒有使用typedef呢?而且這樣的例子在內核代碼中貌似還很多。


Linus 在內核編程規範第五章中,明確規定了不要對 struct 使用 typedef。

因此 Linux 內核代碼應當盡量遵守該規範。簡而言之,除非絕對必要,不要對指針和 struct 使用 typedef 。

至於為什麼不要使用 typedef ,Linus 在文章中也已經解釋得很清楚了。

參考:

https://www.kernel.org/doc/Documentation/CodingStyle


typedef 只是給 struct 起了個別名,使之看起來像是個 C 基本類型,但是,C 語言確實沒有把 struct 當作普通類型,證據是struct 類型的名字空間是獨立的,如可以這樣聲明變數 struct iphdr iphdr;

除了可能少打幾個字外,對 struct 用 typedef 沒有好處,比如 stackoverflow 上 的提前聲明例子,不用 typedef 也沒問題:

頭文件:

struct Point;

struct Point* point_new(int x, int y);

C 文件:

struct Point {...};

同樣隱藏了 struct Point 的實現,只是多了 struct 而已。 用了 typedef ,只是看起來像是實現了一個類型,但對 C 語言的適用環境,反而可能是有害的。


C 語言編程,必須意識到代碼編譯後的物理形態,C
沒有運行時防護措施,沒有類型系統,程序員不僅要實現邏輯目標,為了安全和性能,還要(至少是有可能)設計控制
指令、內存分布的實現,甚至要考慮 cache 的利用率,那麼變數的物理形態是非常重要的信息,使用 typedef 無益於程序員理解當前代碼。

如果代碼只是為了實現邏輯目標(kernel 顯然不是這樣),那麼 C 語言不是最佳選擇,即使是這種情況下用 C 語言, struct 的 typedef 也有其問題,一旦使用,就難以阻止濫用。常見的一個例子,針對 struct 指針 typedef,如:

typedef _Point {...} Point, *PPoint;


是用 Pascal, 將 Point^ 定義為 PPoint, 不算有問題,畢竟沒別的辦法,Point^ 也不是一個單詞。但 C
這麼寫,只會給基於 token 的索引工具製造麻煩,作為程序員,看到 PPoint 時,自然會聯想到這是 struct _Point*, 或
Point*, 但是,誰能保證這是真的?也許在本模塊的前面,已經被一個隨便的傢伙改成了 typedef unsigned int
SmallPoint,*PPoint 了。所以,對 struct 使用 typedef, 是多餘的無益行為。


請看這裡:

Linux-Kernel Archive: Re: [PATCH] 2.5.21


linux的內核用了gcc很多專有擴展,根本沒辦法用其它編譯器來編譯,所以移植性特別差(霧)。所以我覺得作者根本不需要糾結這個問題。我舉個例子:

int sum = ({

int r=0, i=0;

while(i&<100) r+=++i;

r;

});

// 然後sum就等於5050了


意義不明確是一個因素。

印象中遇到過因為用了 typedef 結構體名,和變數重名,導致程序編譯出來的代碼塊異常的情況。更悲催的是編譯器不提示不報錯。


typedef好處顯而易見,壞處和他的好處是一樣的。


推薦閱讀:

如何在 Linux 系統上使用印象筆記 Evernote?
不要雙系統,不要虛擬機,win7系如何換linux系?
向Linux內核提交代碼是否需要很高的水平?
如何學習及利用開源代碼?

TAG:Linux | C編程語言 |