我想学习如何使用宏。
我只是编写一个示例但无法在我的本地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。
对此有合理的解释吗?
如何为所有编译器编写可移植的宏....
感谢。
答案 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
子>