我們在看一些開源的源代碼的時候,經常會看到如下情景:
# 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 www.2cto.com
#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{},理解起來難度不大。反正好好看就問題不大了。
最後,本文有點像代碼貼。文字的部分不多,用貼代碼來理解。說的不好,請大牛們指正,謝謝了 。
摘自 雲端小飛象cg