2014-01-21 21 views
2

考虑下面的代码(live example)'gnu-zero-variadic-macro-arguments`可以安全地忽略吗?

#define TEST_VA(mX, ...) TEST 
#define STRINGIFY_IMPL(mX) #mX 
#define STRINGIFY(mX) STRINGIFY_IMPL(mX) 

#include <iostream> 

int main() 
{ 
    std::cout << STRINGIFY(TEST_VA(1)) << std::endl; 
    std::cout << STRINGIFY(TEST_VA()) << std::endl; 
    return 0; 
} 

铛++ 3.4抱怨:

main.cpp:9:37: warning: must specify at least one argument for '...' parameter of variadic macro [-Wgnu-zero-variadic-macro-arguments] 
    std::cout << STRINGIFY(TEST_VA(1)) << std::endl; 
            ^
main.cpp:1:9: note: macro 'TEST_VA' defined here 
#define TEST_VA(mX, ...) TEST 
     ^
main.cpp:10:33: warning: must specify at least one argument for '...' parameter of variadic macro [-Wgnu-zero-variadic-macro-arguments] 
     std::cout << STRINGIFY(TEST_VA()) << std::endl; 
            ^
main.cpp:1:9: note: macro 'TEST_VA' defined here 
#define TEST_VA(mX, ...) TEST 

我在我的项目的示例代码使用一些复杂的宏等。

为可变宏的...参数传递参数是否安全? (基本上忽略警告)

或者是否会导致问题?

是否明确禁止标准?

+0

@FrançoisMoisan[工作标准草案](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3337.pdf)包含与宏和预处理有关的部分。 –

回答

1

标准在技术上是禁止的。从C++ 11§16.3/ 4(强调):

如果标识符列表中的宏定义不与省略号结束,参数(包括那些 由无预处理标记的参数的个数)在调用函数式宏时应该等于宏定义中参数的个数。 否则,调用中的参数应该多于宏定义中的参数(不包括...。将存在终止调用的令牌的预处理 。

一些编译器可能允许这个作为扩展,但如果你想符合标准的代码,你应该确保始终有一个可变参数宏的省略号参数至少有一个参数。

+0

我依靠零参数可变宏来编译预处理器递归(foreach,元组)。有没有解决方法? –

+0

@VittorioRomeo:这显然取决于你想要做什么。我个人不会推荐用C预处理器来做这样复杂的事情;如果你真的需要这样做,你可以尝试使用另一种更灵活的预处理器,例如GNU m4或自定义脚本。使用类似这样的工具并不太难以集成到基于Makefile的构建系统中,但它会让您的构建系统变得更脆弱并且难以使用。 –

+0

一个基本的例子是countin可变参数。看起来像[提升有同样的问题](http://www.boost.org/doc/libs/1_49_0/boost/preprocessor/variadic/size.hpp) –

相关问题