【问题标题】:Token concatenation using ## gives "not a valid preprocessing token"使用 ## 的令牌连接给出“不是有效的预处理令牌”
【发布时间】:2017-02-02 09:50:44
【问题描述】:

以下代码给出错误:

“粘贴“f32_Q31”和“(”没有给出有效的预处理令牌”

#define INIT_Q(N, name, val) \
    name.value = f32_Q##N##(val);

#define f32_Q31(x)      f32_Q(31,x)
INIT_Q31(name, val)     INIT_Q(31, name, val)
INIT_Q25(name, val)     INIT_Q(25, name, val)

这可以解决吗?

【问题讨论】:

  • 你的意思是name.value = f32_Q##N(val);吗?上面的版本对我来说没有多大意义。
  • 改了,见下文。
  • @Danijel :你似乎忘记了最后两行开头的#defines。
  • @SanderDeDycker 解决了这个问题,谢谢。

标签: c


【解决方案1】:

因为f32_Q31( 不是一个令牌,而是两个。 ( 本身就是一个令牌。连接的结果必须是一个单个有效的token。

如果您的意图是通过扩展另一个宏来初始化 name.value,则可以执行以下操作:

#define INIT_Q(N, name, val) \
    name.value = f32_Q##N(val);

宏名必须是一个有效的标记,而不是整个表达式。


正如 Sander De Dycker 指出的那样,您似乎还从最后两个宏定义中省略了 define

#define INIT_Q31(name, val)     INIT_Q(31, name, val)
#define INIT_Q25(name, val)     INIT_Q(25, name, val)

【讨论】:

  • 已更改。现在它指向 INIT_Q31( 并说:“预期的构造函数、析构函数或在 '(' 标记之前的类型转换”。
  • @Danijel - 当您的代码简化为刚才提到的问题时,它就解决了 (ideone.com/zJTK2o)。如果您还有其他问题,则与您显示的内容或与我的修复建议无关。该修复只允许编译器偶然发现下一个问题。
  • @Danijel 你的 C 编译器知道构造函数和析构函数吗?这很不寻常。也许您正在使用名称中包含大写字母 C 的另一种语言?
  • 我正在使用 C++ 编译器(mingw g++),是的。
  • @Danijel (1) 标记您的问题 C++,而不是 C (2) 考虑不要在 C++ 中使用宏。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-02-26
  • 2011-06-07
  • 1970-01-01
  • 2012-12-10
  • 2012-10-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多