c++ - VARIADIC MACRO 编译错误

标签 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。

这有什么合理的解释吗?

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

谢谢。

最佳答案

在 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/

相关文章:

c++ - 是否可以在 C++ 中以零拷贝方式拼接缓冲区?

C++ 在 lists<string> 和 list<std::pair<string, string>> 之间选择返回类型

c++ - 非托管 C++ : How to dynamically load code?

c++ - 我是否正确理解 C/C++ 严格别名?

c++ - Visual Studio 不显示符号表?

C++ 窗体打开错误

c++ - 使用另一个用户定义数据类型作为参数的用户定义数据类型

c++ - 获取与模板 arg 中传递的函数成员类型相同的类

c++ - 将智能指针作为参数传递给函数

c++ - 头文件中的多重定义