預處理命令

minggoddess發表於2015-07-27

http://www.uml.org.cn/c++/200902104.asp

#define              定義一個預處理巨集
#undef               取消巨集的定義

#include            包含檔案命令
#include_next   與#include相似, 但它有著特殊的用途

#if                      編譯預處理中的條件命令, 相當於C語法中的if語句
#ifdef                判斷某個巨集是否被定義, 若已定義, 執行隨後的語句
#ifndef             與#ifdef相反, 判斷某個巨集是否未被定義
#elif                  若#if, #ifdef, #ifndef或前面的#elif條件不滿足, 則執行#elif之後的語句, 相當於C語法中的else-if
#else                與#if, #ifdef, #ifndef對應, 若這些條件不滿足, 則執行#else之後的語句, 相當於C語法中的else
#endif              #if, #ifdef, #ifndef這些條件命令的結束標誌.
defined            與#if, #elif配合使用, 判斷某個巨集是否被定義

#line                標誌該語句所在的行號
#                      將巨集引數替代為以引數值為內容的字元竄常量
##                   將兩個相鄰的標記(token)連線為一個單獨的標記
#pragma        說明編譯器資訊

#warning       顯示編譯警告資訊
#error            顯示編譯錯誤資訊

--------------------------------------

http://www.cnblogs.com/clover-toeic/p/3851102.html

2.3.2.4 可變引數巨集

     ...在C語言巨集中稱為Variadic Macro,即變參巨集。C99編譯器標準允許定義可變引數巨集(Macros with a Variable Number of Arguments),這樣就可以使用擁有可變參數列的巨集。

     可變引數巨集的一般形式為:

                        #define  DBGMSG(format, ...)  fprintf (stderr, format, __VA_ARGS__)

     省略號代表一個可以變化的參數列,變參必須作為參數列的最右一項出現。使用保留名__VA_ARGS__ 把引數傳遞給巨集。在呼叫巨集時,省略號被表示成零個或多個符號(包括裡面的逗號),一直到到右括號結束為止。當被呼叫時,在巨集體(macro body)中,那些符號序列集合將代替裡面的__VA_ARGS__識別符號。當巨集的呼叫展開時,實際的引數就傳遞給fprintf ()。

     注意:可變引數巨集不被ANSI/ISO C++所正式支援。因此,應當檢查編譯器是否支援這項技術。 

     在標準C裡,不能省略可變引數,但卻可以給它傳遞一個空的引數,這會導致編譯出錯。因為巨集展開後,裡面的字串後面會有個多餘的逗號。為解決這個問題,GNU CPP中做了如下擴充套件定義:

                       #define  DBGMSG(format, ...)  fprintf (stderr, format, ##__VA_ARGS__)

     若可變引數被忽略或為空,##操作將使編譯器刪除它前面多餘的逗號(否則會編譯出錯)。若巨集呼叫時提供了可變引數,編譯器會把這些可變引數放到逗號的後面。

     同時,GCC還支援顯式地命名變參為args,如同其它引數一樣。如下格式的巨集擴充套件:

                              #define  DBGMSG(format, args...)  fprintf (stderr, format, ##args)

     這樣寫可讀性更強,並且更容易進行描述。

     用GCC和C99的可變引數巨集, 可以更方便地列印除錯資訊,如:

1 #ifdef DEBUG
2     #define DBGPRINT(format, args...) \
3         fprintf(stderr, format, ##args)
4 #else
5     #define DBGPRINT(format, args...)
6 #endif

     這樣定義之後,程式碼中就可以用dbgprint了,例如dbgprint ("aaa [%s]", __FILE__)。

     結合第4節的“條件編譯”功能,可以構造出如下除錯列印巨集:

複製程式碼
 1 #ifdef LOG_TEST_DEBUG
 2     /* OMCI除錯日誌巨集 */
 3     //以10進位制格式日誌整型變數
 4     #define PRINT_DEC(x)          printf(#x" = %d\n", x)
 5     #define PRINT_DEC2(x,y)       printf(#x" = %d\n", y)
 6     //以16進位制格式日誌整型變數
 7     #define PRINT_HEX(x)          printf(#x" = 0x%-X\n", x)
 8     #define PRINT_HEX2(x,y)       printf(#x" = 0x%-X\n", y)
 9     //以字串格式日誌字串變數
10     #define PRINT_STR(x)          printf(#x" = %s\n", x)
11     #define PRINT_STR2(x,y)       printf(#x" = %s\n", y)
12 
13     //日誌提示資訊
14     #define PROMPT(info)          printf("%s\n", info)
15 
16     //除錯定位資訊列印巨集
17     #define  TP                   printf("%-4u - [%s<%s>]\n", __LINE__, __FILE__, __FUNCTION__);
18 
19     //除錯跟蹤巨集,在待日誌資訊前附加日誌檔名、行數、函式名等資訊
20     #define TRACE(fmt, args...)\
21     do{\
22         printf("[%s(%d)<%s>]", __FILE__, __LINE__, __FUNCTION__);\
23         printf((fmt), ##args);\
24     }while(0)
25 #else
26     #define PRINT_DEC(x)
27     #define PRINT_DEC2(x,y)
28 
29     #define PRINT_HEX(x)
30     #define PRINT_HEX2(x,y)
31 
32     #define PRINT_STR(x)
33     #define PRINT_STR2(x,y)
34 
35     #define PROMPT(info)
36 
37     #define  TP
38 
39     #define TRACE(fmt, args...)
40 #endif


複製程式碼

 ================================================================

上面都是摘抄,我遇到的問題是這樣的

debug(fmt, args...) debug_printf(__FUNCTION__,fmt,##args)

這樣是編不過的,

debug(fmt, ...) debug_printf(__FUNCTION__,fmt,##__VA_ARGS__)//buyao xiecuo xiahuaxian geshu

這樣才編過

 

相關文章