11

我想让C预处理器为我生成宏(即,我只使用 C99)。我会写一个宏

#define make_macro(in) <...magic here...>

当我把

make_macro(name1)
make_macro(name2)

稍后在代码中,它将扩展为

#define name1(...) name1_fn(name1_info, __VA_ARGS__)
#define name2(...) name2_fn(name2_info, __VA_ARGS__)

然后我就可以使用 name1 和 name2 作为(宏实现的)函数。我认为我在两个步骤中都使用宏:使用宏重复重新填充模板是有意义的,并且可变参数处理除了通过宏之外将不起作用。

那么,<...magic here...> 占位符中包含什么来执行此操作?在这一点上,我开始相信这在 C99 中是不可能的,但也许我遗漏了一些语法细节。

4

6 回答 6

9

这在标准 C 中是不可能的。

于 2009-05-13T20:37:05.150 回答
7

您是否考虑过使用 M4 宏?我认为它们在大多数平台上都可用,所以这不应该是一个限制。

M4 GNU 页面

于 2009-05-14T03:06:07.720 回答
4

正如每个人所说,你不能完全按照你的要求去做。

您可以通过强制 C 预处理器运行两次来执行类似的操作,例如,在 makefile 中使用这样的规则:

.c.pp:
   $(CPP) $< -o $@

然后给你的文件扩展名为 test.pp。Makefile 将运行一次以生成 .c 文件,然后在 .c 文件上正常运行将运行第二次。

就个人而言,我宁愿用 Perl 或其他东西编写一个外部脚本来为我生成 C 代码;它比使用 C 预处理器玩游戏要干净一些。这取决于我们正在谈论多少代码。

于 2009-05-14T04:20:58.600 回答
3

这是不可能的,因为宏只执行一次。

这并不意味着您不能在宏中使用其他宏,但您不能这样做

#define TEST #define HALLO 33

int x = TEST;

然后期望 x 为 33!你会得到一个语法错误,因为你尝试过

int x = #define HALLO 33;

或者编译器可能已经在#define 中抱怨#define。

于 2009-05-13T20:41:10.853 回答
1

根据C99 第 6.10.3.2 节

类函数宏的替换列表中的每个 # 预处理标记应后跟一个参数,作为替换列表中的下一个预处理标记。

因此,#define如果您有一个名为的参数,您当然可以将 a 放入宏中,define但它永远不会满足您的要求。这经常困扰我,因为我必须在 C 中工作,因此不能使用 C++ 模板。

于 2014-02-10T13:56:08.230 回答
0

试试#define make_macro(name,...) name##_fn(name##_info, __VA_ARGS__)

像这样使用:

make_macro(name1)
make_macro(name2,1)

这会产生

name1_fn(name1_info)
name2_fn(name2_info,1)
于 2009-05-13T20:40:55.860 回答