user588477
user588477

Reputation: 165

VARIADIC MACRO compile error

I want to learn how to use macro.

I simply write a sample but failed to compile on my local g++4.9

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

I will get compile error as below

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();
     ^

But the same code can be compiled on ideone.... http://ideone.com/ucEXXz

and also by VS2015.

Is there any reasonable explanation for this?

How can I write a portable macro for all compiler....

Thanks.

Upvotes: 1

Views: 1262

Answers (1)

jxh
jxh

Reputation: 70372

In C, functions that take variable arguments require a prototype declaration, while in C++, all functions require a prototype. The declaration for printf can be found in stdio.h.

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

The ##__VA_ARGS__ syntax is non-standard. It is a "swallow comma if the __VA_ARGS__ is empty" extension implemented by GCC, and seems to have been adopted by other compilers.

Regarding the behavior of -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=

The ##__VA_ARGS__ extension does not conflict with the standard. What is causing it to be rejected by the coliru site is that the -pedantic flag is set.

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

Upvotes: 1

Related Questions