【问题标题】:C: How to Shield Commas in Macro Arguments?C:如何在宏参数中屏蔽逗号?
【发布时间】:2017-09-19 23:11:35
【问题描述】:

有没有一种通用的方法来屏蔽 C 中宏参数中的 cmets?我知道括号可以用于此目的,但在添加括号导致宏输出中的语法错误的情况下,这将不起作用。我听说 ({ }) 可以在 GCC 中屏蔽逗号,但我需要此代码也可以在 VC++ 中工作(最近的版本之一确实符合关于宏中逗号的 C 标准)。在我的情况下,我也不能使用可变参数宏。

我正在尝试做的具体情况是这样的(lengthof 是在别处定义的宏)。我正在尝试为整个事情编写一个宏,因为这将被多次使用,并且拥有多宏解决方案会添加大量额外的测试代码。

#define TEST_UNFUNC(func, res_type, res_set, op_type, op_set) \
{ \
    static const res_type res[] = res_set; \
    static const op_type op[] = op_set; \
    int i; \
    for (i = 0; i < MIN(lengthof(res), lengthof(op)); i++) \
        assert(func(op[i]) == res[i]); \
}

如果可能的话,我想要一个一般性的答案,而不仅仅是针对这个特定宏的解决方法。

【问题讨论】:

  • 您能否更具体地说明这些逗号的来源以及它们需要“屏蔽”的内容?您是否希望能够做类似MYMACRO(1, 2, 3) 的事情并以某种方式表明1, 2 是一个论点?
  • 括号将屏蔽逗号,但如果没有可变参数宏,您将很难将它们从宏输出中删除。 (好吧,IDK没有他们怎么办,也许你会想出一些办法。)
  • @PSkocik 现在没有可变参数宏吗?
  • @o11c OP,它会出现 :(
  • ...真正的答案可能是:使用静态函数,并允许它被内联。

标签: c macros c-preprocessor


【解决方案1】:

使用括号屏蔽逗号,然后将它们传递给特殊的unparen 宏,定义在下面的示例中:

#include <stdio.h>

#define really_unparen(...) __VA_ARGS__
#define invoke(expr) expr
#define unparen(args) invoke(really_unparen args)


#define fancy_macro(a) printf("%s %s\n", unparen(a))

int main()
{
    fancy_macro(("Hello", "World"));
}

这里的诀窍是 invoke 宏强制进行额外的扩展,允许调用 really_unparen,即使源代码中没有括号。

编辑:根据下面的评论,在这种情况下似乎没有必要。虽然我确信我遇到了我需要它的情况有时 ...而且它没有伤害。

【讨论】:

  • 我相信#define fancy_macro(a) printf("%s %s\n", really_unparen a) 应该足够了。 (invokeunparen 宏应该不是必需的)
  • ...呵呵。那么 20 分钟前我有什么没有工作?
  • 请注意,这仍然不符合 C 标准,因为使用了可变参数宏。
  • 您可能需要的示例是传递初始化程序列表或使用comma operator 做一些更挑剔的事情(不记得是怎么做的,但我曾经遇到过这个问题)
  • 啊,是的,使用逗号运算符会返回一个 r 值,所以如果您想分配给它,您可能需要删除括号,添加 = something 并将它们放回原处。所以例如(var1, var2) 会变成(var1, var2 = something),因为(var1, var2) = something 在C 中不起作用
猜你喜欢
  • 2012-11-30
  • 2016-05-14
  • 1970-01-01
  • 2018-11-11
  • 1970-01-01
  • 2010-12-08
  • 2014-01-16
相关资源
最近更新 更多