有没有办法在Visual C中用可变参数列表编写宏?

有没有办法在Visual C中用可变参数列表编写宏?

is there a way to write macros with a variable argument list in visual C++?

据我所知,在gcc中,您可以编写如下内容:

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

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


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

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

完整参考在这里。


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

1
2
3
#define DBGPRINT(args) printf(args);
DBGPRINT(("%s\
"
,"Hello World"));

是的,您可以在Visual Studio C 2005和更高版本中执行此操作(不确定VS 2003)。看一下VA_ARGS。您基本上可以执行以下操作:

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

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

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


对于MSVC 7.1(.NET 2003),此方法有效:

1
2
3
4
5
6
#if defined(DETAILED_DEBUG)
#define DBGPRINT fprintf
#else
__forceinline void __DBGPRINT(...){}
#define DBGPRINT __DBGPRINT
#endif

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


您要查找的内容称为[可变宏](http://msdn.microsoft.com/zh-cn/library/ms177415(VS.80).aspx)。

链接摘要:是的,从VC 2005起。


在MSDN中搜索" VA_ARGS"和va_list!


以下应该起作用。 (请参见可变参数宏的链接)

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

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

差不多。但是,它比这更丑陋(并且您可能不希望宏本身中包含尾随的分号:

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

要使用它:

1
2
DBGPRINT(("%s\
"
,"Hello World"));

(缺少一对括号)。

不确定为什么所有的否定词,原始问题都没有说明VC的版本以及所有编译器均不支持可变参数宏。


推荐阅读