views:

98

answers:

3

Consider this macro:

#define MAKE_TEMPLATE(...) template <typename T, __VA_ARGS__ >

When used with zero arguments it produces bad code since the compiler expects an identifier after the comma. Actually, VC's preprocessor is smart enough to remove the comma, but GCC's isn't. Since macros can't be overloaded, it seems like it takes a seperate macro for this special case to get it right, as in:

#define MAKE_TEMPLATE_Z() template <typename T>

Is there any way to make it work without introducing the second macro?

+3  A: 

According to http://gcc.gnu.org/onlinedocs/gcc/Variadic-Macros.html, GCC does support this, just not transparently.

Syntax is:

   #define MAKE_TEMPLATE(...) template <typename T, ## __VA_ARGS__ >

Anyway, both also support variadic templates in C++0x mode, which is far preferable.

Potatoswatter
Thanks. btw, is this standard behavior, or a gcc thing?
uj2
@uj2: It's GCC; the standard simply forbids empty variadic lists. By the way, this is mixing C99 with C++ anyway, so this code is strictly non-standard unless you're in C++0x… in which case you should…
Potatoswatter
Don't mind the template, it's just a toy example. How is this necessarily 0x, doesn't C++98/03 define variadic macros?
uj2
§16.3/9: "A preprocessing directive of the form `# define identifier lparen identifier-listopt ) replacement-list new-line`defines a function-like macro with parameters, similar syntactically to a function call." — that's all there is to it.
Potatoswatter
@uj2: No, C++03 does not have variadic macros or templates. C++0x provides both.
GMan
iirc this also works in Visual Studio
Alex B
+1  A: 

In case of GCC you need to write it like this:

#define MAKE_TEMPLATE(...) template <typename T, ##__VA_ARGS__ >

If __VA_ARGS__ is empty, GCC's preprocessor removes preceding comma.

qrdl
A: 

First of all beware that variadic macros are not part of the current C++. It seems that they will be in the next version. At the moment they are only conforming if you program in C99.

As of variadic macros with zero arguments, there are tricks à la boost to detect this and to macro-program around it. Googel for empty macro arguments.

Jens Gustedt