如何通过C预处理器(cpp)生成列表?

如何通过C预处理器(cpp)生成列表?,c,c-preprocessor,C,C Preprocessor,我想做如下工作: 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 }; 函数本身很简单。我似乎不能做的是跟踪所有的名称,直到函数表的结尾 我

我想做如下工作:

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 };
函数本身很简单。我似乎不能做的是跟踪所有的名称,直到函数表的结尾

我看了看,但是我找不到任何适合我的东西。
有什么想法吗?

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

这是对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

这有点难看和麻烦,但它可以工作。

使用预处理器执行此操作的正常方法是在一个宏中定义所有函数,将另一个宏作为参数,然后使用其他宏提取所需的内容。例如:

#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\u,可以像您想要实现的那样进行“代码展开”。接近你的例子

#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);
将扩展到以下内容(未经测试)

有一个叫做的东西,用作:

一种可靠地维护代码或数据的并行列表的技术,其对应项必须以相同的顺序出现

这就是它的工作原理:

    #include <stdio.h>

//you create macro that contains your values and place them in (yet) not defined macro
#define COLORS\
    X(red, 91)\
    X(green, 92)\
    X(blue, 94)\

//you can name that macro however you like but conventional way is just an "X"

//and then you will be able to define a format for your values in that macro
#define X(name, value) name = value,
typedef enum { COLORS } Color;
#undef X //just another convention (so you don't use it accidentally, I think)

int main(void)
{
    #define X(name, value) printf("%d, ", name);
    COLORS
    #undef X
    return 0;
}

我想用CPP来做这件事。它是纯C预处理器(以及C++预处理器)。C预处理器不允许宏定义其他宏,或者拥有任何方式进行递归或循环,所以这种技术(也由DDER描述)。如果你把
foo
作为
FUNCTIONS
的一个参数,而不是到处使用PHP,那就不会那么难看了。
    #include <stdio.h>

//you create macro that contains your values and place them in (yet) not defined macro
#define COLORS\
    X(red, 91)\
    X(green, 92)\
    X(blue, 94)\

//you can name that macro however you like but conventional way is just an "X"

//and then you will be able to define a format for your values in that macro
#define X(name, value) name = value,
typedef enum { COLORS } Color;
#undef X //just another convention (so you don't use it accidentally, I think)

int main(void)
{
    #define X(name, value) printf("%d, ", name);
    COLORS
    #undef X
    return 0;
}
#define FUNCTIONS \
F(f1, code1)\
F(f2, code2)\
F(f3, code3)

#define F(name, code) int name(void){code}
FUNCTIONS
#undef F


#define F(name, code) &name,
int (*function_table[])(void) = { FUNCTIONS };
#undef F