如何通过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本身很容易。 我似乎无法做的是跟踪函数表的所有名称,直到最后。

我看了这个问题和这个问题,但我无法为我工作。 有任何想法吗?

使用预处理器执行此操作的常规方法是定义宏中的所有函数,这些函数将另一个宏作为参数,然后使用其他宏来提取所需的内容。 对于你的例子:

 #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) }; 

如果您有C99兼容编译器,则预处理器具有可变长度参数列表。 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 }; 

这有点滥用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 

它有点难看和繁琐,但它的工作原理。

Boost是一个C ++库,但它的预处理器模块仍然适合在C中使用。它提供了一些令人惊讶的高级数据类型和function,可用于预处理器。 你可以看看。