【问题标题】:is there a way to write macros with a variable argument list in visual C++?有没有办法在 Visual C++ 中编写带有变量参数列表的宏?
【发布时间】:2010-09-09 01:34:57
【问题描述】:

据我所知,在 gcc 中你可以这样写:

#define DBGPRINT(fmt...) printf(fmt);

有没有办法在 VC++ 中做到这一点?

【问题讨论】:

    标签: c++ visual-c++ c-preprocessor variadic-macros


    【解决方案1】:

    几乎。它比这更难看(而且你可能不希望宏本身的尾随分号:

    #define DBGPRINT(DBGPRINT_ARGS) printf DBGPRINT_ARGS // note: do not use '(' & ')'
    

    使用它:

    DBGPRINT(("%s\n", "Hello World"));
    

    (缺少一对括号)。

    不知道为什么所有的否定,原始问题没有说明 VC++ 的版本,并且所有编译器都不支持可变参数宏。

    【讨论】:

    • 大概是因为缺少括号意味着它被破坏了......虽然值得注意的是,上面这个更错误的版本得到了 5 个赞成票。你们所有人都错过了简单的#define DBGPRINT printf
    【解决方案2】:

    是的,您可以在 2005 及更高版本的 Visual Studio C++ 中执行此操作(不确定 VS 2003)。看看 VA_ARGS。你基本上可以这样做:

    #define DBGPRINTF(fmt, ...)  printf(fmt, __VA_ARGS__)
    

    宏的变量参数将被传递给作为 '...' args 提供的函数,然后您可以在其中使用 va_args 将它们解析出来。

    VA_ARGS 和宏的使用可能会出现奇怪的行为。因为 VA_ARGS 是可变的,这意味着可以有 0 个参数。这可能会在您不想要的地方留下逗号。

    【讨论】:

    • 如果没有参数,VC++ 会吃掉结尾的逗号,不是吗?
    【解决方案3】:

    您要查找的内容称为 [variadic macros](http://msdn.microsoft.com/en-us/library/ms177415(VS.80).aspx).

    链接摘要:是的,从 VC++ 2005 开始。

    【讨论】:

      【解决方案4】:

      以下应该有效。 (见Variadic macros的链接)

      (下面的示例显示了固定和可变参数。)

      #  define DBGPRINTF(fmt,...) \
          do { \
              printf(fmt, __VA_ARGS__); \
          } while(0)
      

      【讨论】:

        【解决方案5】:

        是的,但仅从 VC++ 2005 开始。您示例的语法是:

        #define DBGPRINT(fmt, ...) printf(fmt, __VA_ARGS__)
        

        完整的参考是here

        【讨论】:

          【解决方案6】:

          在 MSDN 中搜索“VA_ARGS”和 va_list!

          【讨论】:

            【解决方案7】:

            如果您不想使用非标准扩展,则必须提供额外的括号:

            #define DBGPRINT(args) printf(args);
            DBGPRINT(("%s\n", "Hello World"));
            

            【讨论】:

            • 这是大错特错,但得到了赞成......我会单独在定义末尾的分号处解雇某人。您的意图是:#define DBGPRINT(args) printf args ... 但对于这种情况,只需 #define DBGPRINT printf 即可。
            • #define DBGPRINT printf 如果您想从可执行文件中删除所有调试输出代码,则不会这样做。您将留下所有 (...) 参数列表,它至少会触发警告,可能会导致错误和意外的副作用。
            【解决方案8】:

            如果您实际上不需要宏的任何功能(__FILE____LINE__、令牌粘贴等),您可能需要考虑使用stdargs.h 编写可变参数函数。可变参数函数可以调用 vprintf() 来传递变量参数列表,而不是调用 printf()

            【讨论】:

              【解决方案9】:

              对于 MSVC 7.1 (.NET 2003),这是可行的:

              #if defined(DETAILED_DEBUG)
              #define DBGPRINT fprintf
              #else
              __forceinline void __DBGPRINT(...){}
              #define DBGPRINT __DBGPRINT
              #endif
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 2020-08-07
                • 2016-11-06
                • 2013-04-16
                • 1970-01-01
                • 1970-01-01
                • 2011-07-24
                • 1970-01-01
                相关资源
                最近更新 更多