C/C++頭文件規整

C/C++的程序通常有兩個部分,一個是.h頭文件,是通常.c實現文件頭上引入的外部引入(include)的程序接口。自從David Parnas提出信息掩蔽原則後【2】,寫程序要注意把接口和實現分離開來。雖然這篇文章的歷史很悠久,想研究軟件工程的朋友還是一定要讀一讀。

這就帶來了一個小問題:接口,或者我們說的應用程序接口API,往往聲明瞭大於實現需要的內容。比如說,

#include <stdio.h>

int main(int argc, char ** argv) {

printf(“Hello, world!\n”);

}

以上程序是最小的例子了。可是,你要是把頭文件stdio.h全部展開,會引入946行代碼!946行代碼都長什麼樣呢?大概是這個樣子:

。。。

23 #ifndef _STDIO_H

24

25 #if !defined __need_FILE && !defined __need___FILE

26 # define _STDIO_H 1

27 # include <features.h>

28

29 __BEGIN_DECLS

30

31 # define __need_size_t

32 # define __need_NULL

33 # include <stddef.h>

34

35 # include <bits/types.h>

36 # define __need_FILE

37 # define __need___FILE

38 #endif /* Don’t need FILE. */

。。。

比這還絕的是,引入的第27行又遞歸地引入更多的頭文件,又是163行代碼。。。如此一來一去(術語稱爲預處理),你會得到852行代碼,讓編譯器去理解。

可是,從這個程序的意圖上說,你只需要那麼一行聲明:

extern int printf (const char *__restrict __format, …); 就能夠編譯通過了。

問題說清楚了,當你的程序引入頭文件的時候,編譯器不分青紅皁白的處理全部信息,就會浪費寶貴的編譯時間。如果有辦法自動地規整程序,簡化爲只引入必要的信息,就能夠有效地縮減編譯器計算的時間。

Java和其他程序語言當然也有類似的問題,但是在C/C++程序中表現得尤其明顯。因爲系統軟件,比如Linux Kernel, DB2,嵌入式系統,等等往往很複雜,需要定義許許多多頭文件,把它們整理清楚是很有用的工具。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章