gcc支持使用## __VA_ARGS__
约定使用零参数计算宏参数。以下作品使用gcc:
#include <stdio.h>
#define NARGS(...) __NARGS(0, ## __VA_ARGS__, 5,4,3,2,1,0)
#define __NARGS(_0,_1,_2,_3,_4,_5,N,...) N
int main()
{
printf("%d\n", NARGS()); // prints 0
printf("%d\n", NARGS(1)); // prints 1
printf("%d\n", NARGS(1, 2)); // prints 2
return 0;
}
是否有与VisualC ++等效的零参数宏?接受非标准扩展或技巧。
编辑:修复了使用GCC扩展和C ++编译器的示例。
答案 0 :(得分:9)
以下示例在VisualStudio 2010和更新版本,gcc和clang中启用非标准扩展时工作正常。在Microsoft编译器中,它假定当参数count为零时,预处理器将删除AUGMENTER宏中的尾随逗号。这是非标准的,并且还有其他报道。在gcc和clang中,它使用广为人知的## __VA_ARGS__
非标准扩展。
#include <stdio.h>
#ifdef _MSC_VER // Microsoft compilers
#define EXPAND(x) x
#define __NARGS(_1, _2, _3, _4, _5, VAL, ...) VAL
#define NARGS_1(...) EXPAND(__NARGS(__VA_ARGS__, 4, 3, 2, 1, 0))
#define AUGMENTER(...) unused, __VA_ARGS__
#define NARGS(...) NARGS_1(AUGMENTER(__VA_ARGS__))
#else // Others
#define NARGS(...) __NARGS(0, ## __VA_ARGS__, 5,4,3,2,1,0)
#define __NARGS(_0,_1,_2,_3,_4,_5,N,...) N
#endif
int main()
{
// NARGS
printf("%d\n", NARGS()); // Prints 0
printf("%d\n", NARGS(1)); // Prints 1
printf("%d\n", NARGS(1, 2)); // Prints 2
fflush(stdout);
#ifdef _MSC_VER
// NARGS minus 1
printf("\n");
printf("%d\n", NARGS_1(1)); // Prints 0
printf("%d\n", NARGS_1(1, 2)); // Prints 1
printf("%d\n", NARGS_1(1, 2, 3)); // Prints 2
#endif
return 0;
}
使用真实编译器Wandbox和Webcompiler
测试宏答案 1 :(得分:1)
以下是一些适用于gcc(5.3) AND VisualStudio2010的代码:
#include <stdio.h>
#define expand(x) x
#define prefix(...) 0,##__VA_ARGS__
#define lastof10(a,b,c,d,e,f,g,h,i,j,...) j
#define sub_nbarg(...) expand(lastof10(__VA_ARGS__,8,7,6,5,4,3,2,1,0))
#define nbarg(...) sub_nbarg(prefix(__VA_ARGS__))
#define test(...) printf("(%s) ---> %d\n",""#__VA_ARGS__,nbarg(__VA_ARGS__))
int main ()
{
test() ; // () ---> 0
test(1) ; // (1) ---> 1
test(1,2) ; // (1,2) ---> 2
test(1,2,3) ; // (1,2,3) ---> 3
test(1,2,3,4) ; // (1,2,3,4) ---> 4
test(1,2,3,4,5) ; // (1,2,3,4,5) ---> 5
test(1,2,3,4,5,6) ; // (1,2,3,4,5,6) ---> 6
return 0 ;
}
答案 2 :(得分:0)
你可以尝试一下:
#define __NARGS(_1, _2, _3, _4, _5, VAL, ...) VAL
#define NARGS(...) (sizeof(#__VA_ARGS__) == sizeof("") ? 0 : __NARGS(__VA_ARGS__, 5, 4, 3, 2, 1))
适用于g ++(Demo)。
答案 3 :(得分:-1)
使用@ Jarod42和BOOST_PP_VARIADIC_SIZE的概念可以写成如下。
#include <stdio.h>
#include <boost/preprocessor/variadic/size.hpp>
#define FOO(...) (sizeof(""#__VA_ARGS__) == sizeof("") ? 0 : BOOST_PP_VARIADIC_SIZE(__VA_ARGS__))
int main()
{
printf("%d\n", FOO()); // prints 0
printf("%d\n", FOO(1)); // prints 1
printf("%d\n", FOO(1, 2)); // prints 2
return 0;
}