如何通过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