2011-02-05 97 views
11

我想這樣做如下:如何通過C預處理器(cpp)生成列表?

F_BEGIN 

F(f1) {some code} 
F(f2) {some code} 
... 
F(fn) {some code} 

F_END 

,並讓它產生以下

int f1() {some code} 
int f2() {some code} 
... 
int fn() {some code} 

int (*function_table)(void)[] = { f1, f2, ..., fn }; 

函數本身很容易。我似乎無法做的是跟蹤所有的名字,直到function_table結束。

我看着this questionthis question但我沒有得到任何東西爲我工作。 任何想法?

回答

14

使用預處理程序執行此操作的正常方法是,將宏中的所有函數定義爲另一個宏作爲參數,然後使用其他宏提取所需內容。舉個例子:

#define FUNCTION_TABLE(F) \ 
    F(f1, { some code }) \ 
    F(f2, { some code }) \ 
    F(f3, { some code }) \ 
: 

    F(f99, { some code }) \ 
    F(f100, { some code }) 

#define DEFINE_FUNCTIONS(NAME, CODE)  int NAME() CODE 
#define FUNCTION_NAME_LIST(NAME, CODE) NAME, 

FUNCTION_TABLE(DEFINE_FUNCTIONS) 
int (*function_table)(void)[] = { FUNCTION_TABLE(FUNCTION_NAME_LIST) }; 
0

Boost是一個C++庫,但它的預處理器模塊應該仍然適用於C.它提供了一些用於預處理器的令人驚訝的高級數據類型和功能。你可以檢查出來。

+0

我想這樣做只是用CPP。 – 2011-02-05 00:49:35

+0

[Boost :: Preprocessor](http://www.boost.org/doc/libs/1_38_0/libs/preprocessor/)是純C預處理器(以及C++預處理器)。 – 2011-02-05 00:52:09

1

這是濫用CPP,但一種常見的濫用類型。我處理這種情況 這樣定義虛擬宏

#define FUNCTIONS \ 
foo(a,b,c,d) \ 
foo(a,b,c,d) \ 
foo(a,b,c,d) 

now, 

#define foo(a,b,c,d) \ 
a+b ; 

FUNCTIONS 

#undef foo 

後,當你想用不同的同一列表

#define foo(a,b,c,d) \ 
a: c+d ; 

FUNCTIONS 

#undef foo 

這是一個有點醜陋和繁瑣的做了,但它的作品。

+1

如果你把`foo`作爲`FUNCTIONS`的一個參數,而不是讓PHP遍佈整個地方,那麼它就不那麼難看了。 – 2011-02-05 09:29:23

5

如果你有一個C99 complying編譯器,預處理器有可變長度參數列表。 P99有一個預處理器P99_FOR可以做「代碼展開」,就像你想要實現的那樣。要貼近你的例子

#define MYFUNC(DUMMY, FN, I) int FN(void) { return I; } 
#define GENFUNCS(...)           \ 
P99_FOR(, P99_NARG(__VA_ARGS__), P00_IGN, MYFUNC, __VA_ARGS__) \ 
int (*function_table)(void)[] = { __VA_ARGS__ } 

GENFUNCS(toto, hui, gogo); 

將擴大到以下(未經測試)

int toto(void) { return 0; } 
int hui(void) { return 1; } 
int gogo(void) { return 2; } 
int (*function_table)(void)[] = { toto, hui, gogo }; 
相關問題