我想学习如何使用宏。
我只是简单地写了一个示例,但在我的本地 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。
这有什么合理的解释吗?
如何为所有编译器编写一个可移植的宏....
谢谢。
最佳答案
在 C 中,采用可变参数的函数需要原型(prototype)声明,而在 C++ 中,所有函数都需要原型(prototype)。 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
的行为:
The compiler can accept several base standards, such as ‘c90’ or ‘c++98’, and GNU dialects of those standards, such as ‘gnu90’ or ‘gnu++98’. When a base standard is specified, the compiler accepts all programs following that standard plus those using GNU extensions that do not contradict it. For example, -std=c90 turns off certain features of GCC that are incompatible with ISO C90, such as the asm and typeof keywords, but not other GNU extensions that do not have a meaning in ISO C90, such as omitting the middle term of a ?: expression.
GCC documentation for-std=
##__VA_ARGS__
扩展与标准不冲突。导致它被 coliru 站点拒绝的原因是设置了 -pedantic
标志。
Valid ISO C and ISO C++ programs should compile properly with or without this option (though a rare few require -ansi or a -std option specifying the required version of ISO C). However, without this option, certain GNU extensions and traditional C and C++ features are supported as well. With this option, they are rejected.
GCC documentation for-pedantic
关于c++ - VARIADIC MACRO 编译错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33307057/