是否可以防止在Visual C ++中使用空__VA_ARGS__删除逗号?

问题描述 投票:7回答:2

在Visual Studio 2005上,我有一个看起来像这样的宏(已放大!):

#define MY_CALL(FUN, ...) \
  if(prepare(x, y)) {     \
    FUN(__VA_ARGS__);     \
  }
/**/

只要该函数至少接受一个参数,就可以了。

[当函数接受零个参数时,预处理器“有帮助地”删除“尾随逗号”,展开如下所示:

if(prepare(x y)) { funct(); }

很好,不是吗?

如何修复此宏,以便在Visual C ++(VS 2005)上将其与零__VA_ARGS__一起使用?


显然是this is a bug in VS2005

visual-c++ macros preprocessor variadic-macros
2个回答
6
投票

不幸的是,我不再使用Visual C ++(因此无法验证此方法是否有效,但是可以尝试吗?

#define MY_CALL(FUN, ...) \
  if(prepare(x, y)) {     \
    int fail[] = {0,}     \
    FUN(__VA_ARGS__);     \
  }

使用gcc 4.2,在这种情况下都允许{0,}{0},因此,如果逗号被删除还是不被删除,都没有关系。但是,我不确定这是规范中普遍接受的,是常用的扩展还是gcc特定的东西。

如果Visual C ++允许{0,}语法is,那么这有望解决您的问题(假设我正确理解__VA_ARGS__之前的最新逗号是被错误删除的内容,无论它在哪里出现在语法中)。


0
投票

我已经找到一种无需创建任何C ++代码膨胀的方法。只需为自己定义此宏即可:

#define PREVENT_EATING_COMMA_IMPL(x, __VA_ARGS__) __VA_ARGS__
#define PREVENT_EATING_COMMA(...) PREVENT_EATING_COMMA_IMPL(x, __VA_ARGS__)

然后

#define DEFER(...) PREVENT_EATING_COMMA(__VA_ARGS__)

即使您没有在其中传递任何参数,也不会吃逗号,效果很好。在您的示例中,您将__VA_ARGS__包装在PREVENT_EATING_COMMA(__VA_ARGS__)中。

© www.soinside.com 2019 - 2024. All rights reserved.