2016-09-02 15 views
13

我有這樣一個宏:C預處理程序刪除後面的逗號

#define C(a...) (char *[]){ a, 0 } 

這適用於非空的論點:

C("a", "b") => (char *[])("a", "b", 0 } 

但我想刪除尾隨逗號時提供一個空參數:

C() => (char *[]){ , 0 } 

這可能嗎?

+1

目前沒有便攜的方式來做到這一點。 (我相信有一個懸而未決的提案,可以讓你構建這樣的東西,不過。) –

+0

我的意思是,看看Boost.Preprocessor,也許有一些神奇的東西可以實現這一點。 (這也應該用C工作。) –

+0

沒問題,我只是好奇,如果有可能的話。因爲它不是,所以我只是定義了一些類似於'#define C0(char * []){0}的東西' –

回答

4

至少在GCC 5.4.0,在Cygwin(default -std=gnu11),這似乎做你想做的(假設我正確理解你的問題):

#define C(a...) (char *[]){ a 0 } 
           ^no comma!  
C("a", "b",) 
     ^comma here 
=> (char *[])("a", "b", 0 } 

C() 
=> (char *[]){ 0 } 

測試與gcc -E並沒有其他的命令行選項。

編輯正如@KerrekSB所述,這是不可移植的。的GCC preprocessor docs有這樣說的(強調):

以上的說明是不明確的關於其中唯一的宏參數是一個可變參數參數的情況下,因爲它是〔如在這種情況下,編。]試圖區分根本沒有論據是否是一個空洞的論證或缺少的論證毫無意義。在這種情況下,C99標準清楚地表明逗號必須保持不變,但是現有的GCC擴展用於吞下逗號。 因此CPP在符合特定C標準時保留逗號,否則將丟棄它。

所以上述在GCC中運行良好,但可能不會在其他編譯器上運行。但是,它對我的​​工作gcc -std=c90 -E(或c99c11)。

+0

在美學意義上,必須在宏的每次調用中輸入尾隨逗號是個小麻煩,說話是不值得的,但從技術上看,這是該問題唯一的(現在)實際解決方法。 –