47

我正在实现 X 宏,但我遇到了一个简单的宏扩展问题。this这个宏(见下文)通过包含在文章中被用于几个宏使用示例。编译器给出了一条错误消息,但我可以通过在 GCC 编译器中使用-E标志来查看有效的 C 代码。

宏 X-list 定义如下:

#define LIST \
  X(red, "red") \
  X(blue, "blue") \
  X(yellow, "yellow")

进而:

#define X(a, b) foo.##a = -1;
  LIST;
#undef X

但是 gcc 给出了以下错误消息:

lixo.c:42:1: error: pasting "." and "red" does not give a valid preprocessing token
lixo.c:42:1: error: pasting "." and "blue" does not give a valid preprocessing token
lixo.c:42:1: error: pasting "." and "yellow" does not give a valid preprocessing token

就像我说的,我可以通过-E在 gcc 上使用 switch 来查看有效的 C 代码:

lixo.c:42:1: error: pasting "." and "red" does not give a valid preprocessing token
lixo.c:42:1: error: pasting "." and "blue" does not give a valid preprocessing token
lixo.c:42:1: error: pasting "." and "yellow" does not give a valid preprocessing token
  foo.red = -1; foo.blue = -1; foo.yellow = -1;;

什么是有效的预处理令牌?有人可以解释一下吗?

(在您说“为什么不只是初始化或memset()?”之前,这不是我的真实代码。)

4

1 回答 1

57

.分隔标记,因此您不能使用##as.red不是有效标记。仅##当您将两个标记连接成一个标记时才会使用。

这有效:

#define X(a, b) foo.a = -1;

什么是有效的处理令牌?有人可以解释一下吗?

这就是被解析/解析的内容。foo.bar将被解析为 3 个令牌(两个标识符和一个运算符):foo . bar如果您使用##,您只会得到 2 个令牌(一个标识符和一个无效令牌):foo .bar

于 2012-11-04T05:59:48.450 回答