VARIADIC MACRO编译错误

时间:2015-10-23 16:16:37

标签: c++

我想学习如何使用宏。

我只是编写一个示例但无法在我的本地g ++ 4.9上编译

#define P(...) printf("13", ##__VA_ARGS__)
int main() {
// your code goes here
P();
return 0;
}

我将收到编译错误,如下所示

g++ -std=c++14 -O2 -Wall -pedantic -pthread main.cpp && ./a.out
main.cpp: In function 'int main()':
main.cpp:4:42: error: expected primary-expression before ')' token
 #define P(...) printf("13", ##__VA_ARGS__)
                                          ^
main.cpp:7:5: note: in expansion of macro 'P'
     P();
     ^

但是可以在ideone上编译相同的代码.... http://ideone.com/ucEXXz

以及VS2015。

对此有合理的解释吗?

如何为所有编译器编写可移植的宏....

感谢。

1 个答案:

答案 0 :(得分:1)

在C中,采用变量参数的函数需要原型声明,而在C ++中,所有函数都需要原型。 printf的声明可以在stdio.h中找到。

#include <stdio.h>
#define P(...) printf("13", ##__VA_ARGS__)
int main() {
P();
return 0;
}

##__VA_ARGS__语法是非标准的。它是由GCC实施的“__VA_ARGS__为空”扩展的“燕子逗号”,似乎已被其他编译器采用。

关于-std=c++14的行为:

  

编译器可以接受几个基本标准,例如'c90'或'c ++ 98',以及这些标准的GNU方言,例如'gnu90'或'gnu ++ 98'。当指定基本标准时,编译器接受遵循该标准的所有程序以及使用不与其相矛盾的GNU扩展的程序。例如,-std = c90关闭了与ISO C90不兼容的GCC的某些功能,例如asm和typeof关键字,但没有其他在ISO C90中没有意义的GNU扩展,例如省略中间词a?:表达式。   
  <子> GCC documentation for -std=

##__VA_ARGS__扩展名与标准版不冲突。 coliru网站拒绝它的原因是-pedantic标志已设置。

  

有效的ISO C和ISO C ++程序应该在有或没有此选项的情况下正确编译(尽管少数几个需要-ansi或-std选项指定所需的ISO C版本)。但是,如果没有此选项,则还支持某些GNU扩展和传统的C和C ++功能。使用此选项,它们将被拒绝   <子> GCC documentation for -pedantic