C #pragma once 與 #ifdef

原文鏈接:https://blog.csdn.net/hkx1n/article/details/4313357

前言

在vc6的時代頭文件一般使用ifndef define endif,在vc7的時代頭文件一般成了pragma once,不知道有沒有人深究其中的意義。

爲什麼有這樣的代碼,是爲了頭文件不被重複引用,那樣編譯器抱錯的,這兩種方法都是同樣的目的,有沒有區別呢?

還是舉例來說明,可能有好幾個庫,每個庫內部可能都有public.h這個文件,如果使用

#ifndef _public_h_

#define _public_h_
...
#endif

那麼當一個文件同時引用兩個這樣的庫時,後一個庫裏的文件就不被編譯了,而#pragma once可以保證文件只被編譯一次。

看起來#pragma once比ifndef #define endif要好,那麼ifndef define endif的地方都使用pragma once好了。今天碰到了又一個例子,比如你有一個zlib.h在幾個庫都用到,而爲了方便,把zlib每個目錄下copy了一分,因爲這個文件不會作修改,已經很完整了,這個時候如果使用pragma once,就會重複定義,看來ifndef define endif還是又派上用場的地方。

建議:對於公有或者接口的文件,使用ifndef define endif,對於內部的文件使用pragma once。

#pragma once 與 #ifndef #define #endif 的區別

對於#pragma once,根據MSDN解說,能夠防止一個文件被多次包含。與#ifndef #define #endif形式的文件保護相比,前者是平臺相關的,可移植性比較差,但是它效率更高,因爲它不需要去打開包含的文件,就可以判斷這個文件有沒有被包含。當然這個工作是系統幫我們完成的。

後者的優點在於它是語言相關的特性,所以可移植性好。但是在包含一個文件的時候,只有打開這個文件,根據文件的保護宏是否已經被定義來判斷此文件是否已經被包含過。效率相對較低。當然在#include的時候,程序員也可以自己判斷所要包含的文件的保護宏是否已經被定義,來決定是否要包含這個文件。類似下面的代碼:

/* 主觀理解,僅供參考 */
#ifndef _FILE_H_
#include "file.h"

#endif

這樣作可以得到較高的效率,而且保證可移植性。但是文件之間的依賴性較高,如果一個文件的保護宏改變的話,所有使用如上形式包含這個文件的文件都要修改。有悖於模塊化的思想。

思考

mavlink通信協議採用頭文件(*.h)來封裝協議,其中頭文件即是使用#progama once,比用(*.c)加(*.h)的方式更便捷。

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