#ifdef,#ifndef,#define,#endif解析(原)


    我們在看一些開源的源代碼的時候,經常會看到如下情景:

# if defined(_PTHREADS) && !defined(_NOTHREADS)
#     define __STL_PTHREADS
# endif
 
# if defined(_UITHREADS) && !defined(_PTHREADS) && !defined(_NOTHREADS)
#     define __STL_UITHREADS
# endif
 
# if defined(__sgi) && !defined(__GNUC__)
#   include <standards.h>
#   if !defined(_BOOL)
#     define __STL_NO_BOOL
#   endif
#   if defined(_MIPS_SIM) && _MIPS_SIM == _ABIO32
#     define __STL_STATIC_CONST_INIT_BUG
#   endif
#   if defined(_WCHAR_T_IS_KEYWORD)
#     define __STL_HAS_WCHAR_T
#   endif
#  .......
#   if _COMPILER_VERSION >= 730 && defined(_STANDARD_C_PLUS_PLUS)
#     define __SGI_STL_USE_AUTO_PTR_CONVERSIONS
#   endif
# endif

    曾經菜鳥和現在依然還是菜鳥的我尷尬,對於這個滿眼的#ifdef,#ifndef,#define,#endif,心里犯怵。我擦,這是神馬鳥東西啊惡魔!其實,這些是條件編譯。對於不同平台,許多的參數定義都不是不同,那么條件編譯就是對付跨平台的炸彈,炸毀平台之間的藩籬。

    先說說#ifndef,#define,#endif,我們對此十分的熟悉。在我們項目的許多頭文件里面,我們經常是這樣:

#ifndef JSON_AUTOLINK_H_INCLUDED
#define JSON_AUTOLINK_H_INCLUDED
 
.......
 
#endif // JSON_AUTOLINK_H_INCLUDED

    話說這樣是為了解決重復定義的問題太陽。例如:我在a.h中定義了class A,在b.h中也定義了class A,那么在c.cpp中都包含了a.h和b.h,按照包含頭函數的習慣,這個class A是重復定義了。為了防止這樣情況的出現,就出現上面的做法。

    在來說說,#ifdef和#endif。一般情況下,源程序中所有的行都參加編譯。但是,有時希望對其中一部分內容只在滿足一定條件才進行編譯,也就是對一部分內容指定編譯的條件,這就是“條件編譯”。那么怎么使用呢?惡魔看看以下格式:

#ifdef 標識符
 
程序段1
 
#else
 
程序段2
 
#endif

    那么,我們在config文件中就可以來選擇說,要編譯那個程序段。這是不是很爽呢?大笑我不用寫兩份,只寫一份,然后編譯的時候調整以下就好了。

    例如下面的代碼太陽

#ifdef JSON_VALUE_USE_INTERNAL_MAP
   class ValueAllocator;
   class ValueMapAllocator;
   class ValueInternalLink;
   class ValueInternalArray;
   class ValueInternalMap;
#endif // #ifdef JSON_VALUE_USE_INTERNAL_MAP

    我在config文件中沒有#define JSON_VALUE_USE_INTERNAL_MAP的時候,上面這段代碼是被忽略的破碎的心。當我在config文件中這樣寫:

# define JSON_USE_EXCEPTION 1
 
# define JSON_VALUE_USE_INTERNAL_MAP    // 增加了這個之后,整個項目中的JSON_VALUE_USE_INTERNAL_MAP這個部分就可以進行編譯了
 
# ifdef JSON_IN_CPPTL
#  include <cpptl/config.h>
#  ifndef JSON_USE_CPPTL
#   define JSON_USE_CPPTL 1
#  endif
# endif
......

    #define這個東西可以定義宏,參數之類的,也可以作為條件編譯中的閥門,例如上面的例子。宏就不介紹了。我不大喜歡,因為我可以用內聯函數來代替。太陽內聯函數多帥啊,不好好用可惜的說。

    在次將眼光轉到本文開始的地方,有許多的條件編譯語句,有些需要解釋。

# if defined(_PTHREADS) && !defined(_NOTHREADS)    // 假如有定義_PTHREADS和沒有定義_NOTHREADS,那么就定義__STL_PTHREADS吧。聽起來有點囧!
#     define __STL_PTHREADS
# endif

    這種條件編譯語句很像if(){}else{},理解起來難度不大。反正好好看就問題不大了。

    最后,本文有點像代碼貼。文字的部分不多,用貼代碼來理解。說的不好,請大牛們指正,謝謝了吐舌鬼臉

 

參考文獻:

1. 《C語言程序設計》

2. 《C和指針》

3. 《C專家編程》


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM