【问题标题】:Why does this variadic argument count macro fail with VC++?为什么这个可变参数计数宏在 VC++ 中失败?
【发布时间】:2011-07-28 16:19:43
【问题描述】:

我得到了以下实现来获取可变参数宏中的参数数量(目前限制为 16 个参数)。但是,对于 VS2010,无论传递多少参数,输出始终为 1With GCC,输出是正确的,让我得出结论,我一定错过了 MSVC (10) 的特定内容。

#define PP_NARGS(...) \
    _xPP_NARGS_IMPL(__VA_ARGS__,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0)

#define _xPP_NARGS_IMPL(x1,x2,x3,x4,x5,x6,x7,x8,x9,x10,x11,x12,x13,x14,x15,N,...) N

int main(){
    int i = PP_NARGS(A,V,C,X,Y,Z);

    std::cout << i;

    std::cin.get();
    return 0;
}

所以,问题如标题所述,任何帮助将不胜感激。

【问题讨论】:

    标签: c++ visual-studio-2010 visual-c++ c-preprocessor


    【解决方案1】:

    以下解决方法有帮助吗?

    #define EXPAND(x) x
    #define PP_NARGS(...) \
        EXPAND(_xPP_NARGS_IMPL(__VA_ARGS__,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0))
    

    我认为你的宏并没有特别错,但是 MSVC 的 __VA_ARGS__ 扩展似乎与 C99 的行为不同。

    【讨论】:

    • 天啊,它确实有效!惊人的!你有解释为什么吗?
    • 我很高兴能帮上忙 :-) 老实说,我无法解释为什么(Doh)。正如我在答案中所写,我认为您的宏在 C99 标准中很好。我将EXPAND 的内容解释为纯粹的变通方法,并且其中可能没有任何技术上有趣的问题......根据here,这似乎是VC 的错误行为。
    • 非常感谢您提供此解决方法。按照 VS14 CTP3 中的描述工作(其中一个错误,在 2008 年被 MS 承认 [参见 Ise 的链接],仍然存在)。
    • @IseWisteria @Xeo 在我的调查中,我刚刚遇到了类似的问题 (stackoverflow.com/questions/38209120/…),我意识到 __VA_ARGS__ 被扩展它们被传递到宏。在您的情况下,x1 整体变为 A,V,C,X,Y,ZEXPAND 技巧迫使它提前展开。
    【解决方案2】:

    问题似乎是 Visual Studio 正在扩展 __VA_ARGS__ 将其传递到后续宏中,而 gcc 在传递之前将其扩展。

    在您的情况下,PP_NARGS(A,V,C,X,Y,Z)A,V,C,X,Y,Z 绑定到__VA_ARGS__,然后将其作为一个整体传递给_xPP_NARGS_IMPL

    作为测试,运行:

    #define PP_NARGS(...) \
        _xPP_NARGS_IMPL(__VA_ARGS__,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0)
    
    #define _xPP_NARGS_IMPL(x1,x2,x3,x4,x5,x6,x7,x8,x9,x10,x11,x12,x13,x14,x15,N,...) \
      (std::cout << #x1 << std::endl, N) 
    
    int main() {
      int i = PP_NARGS(A, V, C, X, Y, Z);
      std::cout << i;
      return 0;
    }
    

    您将看到A, V, C, X, Y, Z 打印在屏幕上,而不仅仅是您可能期望的A


    正如 Ise Wisteria 已经建议的那样,一个可能的解决方案是通过以下方式强制扩展:

    #define EXPAND(x) x
    #define PP_NARGS(...) \
        EXPAND(_xPP_NARGS_IMPL(__VA_ARGS__,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-19
      • 2014-07-14
      • 1970-01-01
      • 2017-09-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多