Variadic macros with zero arguments, and commas - c++

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 separate 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?

No, because the macro invocation MAKE_TEMPLATE() does not have zero arguments at all; it has one argument comprising zero tokens.
Older preprocessors, apparently including GCC at the time this answer was originally written, sometimes interpreted an empty argument list as you'd hope, but the consensus has moved toward a stricter, narrower extension which more closely conforms to the standard.
To get the answer below to work, define an additional macro parameter before the ellipsis:
#define MAKE_TEMPLATE(UNUSED, ...) template <typename T, ## __VA_ARGS__ >
and then always put a comma before the first argument when the list is not empty:
MAKE_TEMPLATE(, foo )
Old answer
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.

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.

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.

Related

How to concatenate/join __VA_ARGS__ with delimiters/separators?

I would like to expand a variadic macro to another macro that takes a single argument, which is formed by joining the variadic arguments with a delimiter/separator (e.g. "_"). Something like this:
#define FOO(...)
FOO(a, b, c, d);
which expands into
#define BAR(X)
BAR(a_b_c_d);
I know there is __VA_ARGS__ for working with the variadic parameters, and ## for concatenation. How do I use them together to achieve what I want (preferably using C++17 and older language features, without libraries such as Boost)?
First, there are no language feature that directly tackles the question you are trying to solve. (there might be complier specific ones, but I don't know).
However, if you know the upper limit of the amount of argument that macro can take(preferably not too many), you can use this answer as a guide to iterate through the __VA_ARGS__: Is it possible to iterate over arguments in variadic macros?
On the other hand, Boost.Preprocessor is a header only library. While it is a pretty heavy macro-only library that could bring a lot of ugliness behind the scene, it does offer simple ways to handle macros that take up to thousands of parameter.
Here's a quick one that should work for you:
#define CAT_OP(index, state, elem) BOOST_PP_CAT(state, BOOST_PP_CAT(_, elem))
#define CAT_SEQ(seq) BOOST_PP_SEQ_FOLD_LEFT(CAT_OP, BOOST_PP_SEQ_HEAD(seq), BOOST_PP_SEQ_TAIL(seq))
#define CAT_VA_ARGS(...) CAT_SEQ(BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__))
Demo.
It treats the variadic as a Sequence, then performs a left fold over the sequence with concat operation.

How to resolve "must specify at least one argument for '...' parameter of variadic macro"

You can define a variadic macro in C++ like:
#define FOO(x, ...) bar(x, __VA_ARGS__)
But calling FOO as FOO(1) results in the macro expansion bar(1,) which is obviously a syntactical error and won't compile.
Therefore GCC includes a GNU extension:
#define FOO(x, ...) bar(x, ##__VA_ARGS__)
which would expand the given example to the desired result bar(1). Although __VA_ARGS__ is a GNU extension it's support by clang too, but which emits a warning under the -pedantic flag:
warning: token pasting of ',' and __VA_ARGS__ is a GNU extension [-Wgnu-zero-variadic-macro-arguments].
Therefore C++20 includes a new mechanism to achieve the desired result in a standard compliant way:
#define FOO(x, ...) bar(x __VA_OPT__(,) __VA_ARGS__)
This will add the , only if the following __VA_ARGS__ are not empty, otherwise it will omit the ,. This new extension currently works with the GCC and clang trunks (with the -std=c++2a flag enabled): https://godbolt.org/z/k2nAE6.
My only problem is that clang emits a warning under -pedantic:
warning: must specify at least one argument for '...' parameter of variadic macro [-Wgnu-zero-variadic-macro-arguments] (GCC does not emit a warning).
But why? This only seems to make sense if someone only uses __VA_ARGS__ and passes no arguments to the macro. But with the new extension __VA_OPT__ I explicitly handle the case for which no argument is given.
So why would clang emit a warning in this case and how can I work around it?
This is already legal in C++20; it appears that Clang just hasn't updated their warnings yet.
The C++20 standard (from N4868) says in [cpp.replace.general]/5:
If the identifier-list in the macro definition does not end with an ellipsis [...] Otherwise, there shall be at least as many arguments in the invocation as there are parameters in the macro definition (excluding the ...). There shall exist a ) preprocessing token that terminates the invocation.
Compare with the bolded section with the equivalent statement in C++17's [cpp.replace]/4 (from N4659):
If the identifier-list in the macro definition does not end with an ellipsis [...] Otherwise, there shall be more arguments in the invocation than there are parameters in the macro definition (excluding the ...). There shall exist a ) preprocessing token that terminates the invocation.
There is a similar comparison to be made between C++20's [cpp.replace.general]/15 and C++17's [cpp.replace]/12.
That is, C++17 had a requirement for FOO(x, ...) to be passed at least two arguments; C++20 has weakened that to only require one. Clang's -pedantic doesn't seem to have caught up yet.

Can a preprocessor macro expand just some pasted parameters?

I know that in expanding a function-like preprocessor macro, the # and ## tokens in the top-level substitution list essentially act "before" any macro expansions on the argument. For example, given
#define CONCAT_NO_EXPAND(x,y,z) x ## y ## z
#define EXPAND_AND_CONCAT(x,y,z) CONCAT_NO_EXPAND(x,y,z)
#define A X
#define B Y
#define C Z
then CONCAT_NO_EXPAND(A,B,C) is the pp-token ABC, and EXPAND_AND_CONCAT(A,B,C) is the pp-token XYZ.
But what if I want to define a macro that expands just some of its arguments before pasting? For example, I would like a macro that allows only the middle of three arguments to expand, then pastes it together with an exact unexpanded prefix and an exact unexpanded suffix, even if the prefix or suffix is the identifier of an object-like macro. That is, if again we have
#define MAGIC(x,y,z) /* What here? */
#define A X
#define B Y
#define C Z
then MAGIC(A,B,C) is AYC.
A simple attempt like
#define EXPAND(x) x
#define MAGIC(x,y,z) x ## EXPAND(y) ## z
results in an error 'pasting ")" and "C" does not give a valid preprocessing token". This makes sense (and I assume it's also producing the unwanted token AEXPAND).
Is there any way to get that sort of result using just standard, portable preprocessor rules? (No extra code-generating or -modifying tools.)
If not, maybe a way that works on most common implementations? Here Boost.PP would be fair game, even if it involves some compiler-specific tricks or workarounds under the hood.
If it makes any difference, I'm most interested in the preprocessor steps as defined in C++11 and C++17.
Here's a solution:
#define A X
#define B Y
#define C Z
#define PASTE3(q,r,s) q##r##s
#define MAGIC(x,y,z,...) PASTE3(x##__VA_ARGS__,y,__VA_ARGS__##z)
MACRO(A,B,C,)
Note that the invocation "requires" another argument (see below for why); but:
MACRO(A,B,C) here is compliant for C++20
MACRO(A,B,C) will "work" in many C++11/C++17 preprocessors (e.g., gnu/clang), but that is an extension not a C++11/C++17 compliant behavior
I know that in expanding a function-like preprocessor macro, the # and ## tokens in the top-level substitution list essentially act "before" any macro expansions on the argument.
To be more precise, there are four steps to macro expansion:
argument identification
argument substitution
stringification and pasting (in an unspecified order)
rescan and further replacement
Argument identification associates parameters in the macro definition with arguments in an invocation. In this case, x associates with A, y with B, z with C, and ... with a "placemarker" (abstract empty value associated with a parameter whose argument has no tokens). For C++ preprocessors up to C++20, use of a ... requires at least one parameter; since C++20's addition of the __VA_OPT__ feature, use of the ... in an invocation is optional.
Argument substitution is the step where arguments are expanded. Specifically, what happens here is that for each parameter in the macro's replacement list (here, PASTE3(x##__VA_ARGS__,y,__VA_ARGS__##z)), where said parameter does not participate in a paste or stringification, the associated argument is fully expanded as if it appeared outside of an invocation; then, all mentions of that parameter in the replacement list that do not participate in stringification and paste are replaced with the expanded result. For example, at this step for the MAGIC(A,B,C,) invocation, y is the only mentioned qualifying parameter, so B is expanded producing Y; at that point we get PASTE3(x##__VA_ARGS__,Y,__VA_ARGS__##z).
The next step applies pastes and stringification operators in no particular order. Placemarker's are needed here specifically because you want to expand the middle and not the end, and you don't want extra stuff; i.e., to get A to not expand to X, and to stay A (as opposed to changing to "A"), you need to avoid argument substitution specifically. a.s. is avoided in only two ways; pasting or stringifying, so if stringification doesn't work we have to paste. And since you want that token to stay the same as what you had, you need to paste to a placemarker (which means you need one to paste to, which is why there's another parameter).
Once this macro applies the pastes to the "placemarkers", you wind up with PASTE3(A,Y,C); then there is the rescan and further replacement step, during which PASTE3 is identified as a macro invocation. Fast forwarding, since PASTE3 pastes its arguments, a.s. doesn't apply to any of them, we do the pastes in "some order" and we wind up with AYC.
As a final note, in this solution I'm using a varying argument to produce the placemarker token precisely because it allows invocations of the form MACRO(A,B,C) in at least C++20. I'm left-pasting that to z because that makes the addition at least potentially useful for something else (MAGIC(A,B,C,_) would use _ as a "delimiter" to produce A_Y_C).

Are empty macro arguments legal in C++11?

I sometimes deliberately omit macro arguments. For example, for a function-like macro like
#define MY_MACRO(A, B, C) ...
I might call it as:
MY_MACRO(, bar, baz)
There are still technically 3 arguments; it's just that the first one is "empty". This question is not about variadic macros.
When I do this I get warnings from g++ when compiling with -ansi (aka -std=c++98), but not when I use -std=c++0x. Does this mean that empty macro args are legal in the new C++ standard?
That's the entirety of my question, but anticipating the "why would you want to?" response, here's an example. I like keeping .h files uncluttered by function bodies, but implementing simple accessors outside of the .h file is tedious. I therefore wrote the following macro:
#define IMPLEMENT_ACCESSORS(TEMPLATE_DECL, RETURN_TYPE, CLASS, FUNCTION, MEMBER) \
TEMPLATE_DECL \
inline RETURN_TYPE* CLASS::Mutable##FUNCTION() { \
return &MEMBER; \
} \
\
TEMPLATE_DECL \
inline const RETURN_TYPE& CLASS::FUNCTION() const { \
return MEMBER; \
}
This is how I would use it for a class template that contains an int called int_:
IMPLEMENT_ACCESSORS(template<typename T>, int, MyTemplate<T>, Int, int_)
For a non-template class, I don't need template<typename T>, so I omit that macro argument:
IMPLEMENT_ACCESORS(, int, MyClass, Int, int_)
If I understand correctly, empty macro argument is allowed since C99 and
C++0x(11).
C99 6.10.3/4 says:
... the number of arguments (including those arguments consisting of
no preprocessing tokens) shall equal the number of parameters ...
and C++ N3290 16.3/4 has the same statement, while C++03 16.3/10 mentions:
... any argument consists of no preprocessing tokens, the behavior is
undefined.
I think empty argument comes under the representation arguments consisting of
no preprocessing tokens above.
Also, 6.10.3 in Rationale for International Standard Programming Languages C rev. 5.10
says:
A new feature of C99: Function-like macro invocations may also now
have empty arguments, that is, an argument may consist of no
preprocessing tokens.
Yes. The relevant bit is 16.3/11
The sequence of preprocessing tokens bounded by the outside-most
matching parentheses forms the list of arguments for the function-like
macro. The individual arguments within the list are separated by comma
preprocessing tokens.
There's no requirement that a single argument corresponds to precisely one token. In fact, the following section makes it clear that there can be more than one token per argument:
Before being substituted, each argument’s preprocessing tokens are
completely macro replaced as if they formed the rest of the
preprocessing file
In your case, one argument happens to correspond to zero tokens. That doesn't cause any contradiction.
[edit]
This was changed by N1566 to bring C++11 in line with C99.
When I do that I normally put a comment in place of the argument.
Place a macro that will be expanded to the empty string.
#define NOARG
...
MY_MACRO(/*Ignore this Param*/ NOARG, bar, baz)
PS. I got no warning with g++ with or without the -std=c++98 flag.
g++ (Ubuntu 4.4.3-4ubuntu5) 4.4.3
g++ (Apple Inc. build 5666) 4.2.1

What does the tilde (~) in macros mean?

Seen on this site, the code shows macro invocations using a tilde in parentheses:
HAS_COMMA(_TRIGGER_PARENTHESIS_ __VA_ARGS__ (~))
// ^^^
What does it mean / do? I suspect it to just be an empty argument, but I'm not sure. Is it maybe specific to C(99) like the __VA_ARGS__ is specific to C99 and existent in C++?
On the introduction page of Boost.Preprocessor, an example is given in A.4.1.1 Horizontal Repetition
#define TINY_print(z, n, data) data
#define TINY_size(z, n, unused) \
template <BOOST_PP_ENUM_PARAMS(n, class T)> \
struct tiny_size< \
BOOST_PP_ENUM_PARAMS(n,T) \
BOOST_PP_COMMA_IF(n) \
BOOST_PP_ENUM( \
BOOST_PP_SUB(TINY_MAX_SIZE,n), TINY_print, none) \
> \
: mpl::int_<n> {};
BOOST_PP_REPEAT(TINY_MAX_SIZE, TINY_size, ~) // Oh! a tilde!
#undef TINY_size
#undef TINY_print
An explanation is provided below:
The code generation process is kicked off by calling BOOST_PP_REPEAT, a higher-order macro that repeatedly invokes the macro named by its second argument (TINY_size). The first argument specifies the number of repeated invocations, and the third one can be any data; it is passed on unchanged to the macro being invoked. In this case, TINY_size doesn't use that data, so the choice to pass ~ was arbitrary. [5]
(emphasis mine)
And there is the note:
[5] ~ is not an entirely arbitrary choice. Both # and $ might have been good choices, except that they are technically not part of the basic character set that C++ implementations are required to support. An identifier like ignored might be subject to macro expansion, leading to unexpected results.
The tilde, therefore, is simply a place holder because an argument is required, but none is necessary. Since any user-defined identifier wannabe could be expanded, you need to use something else.
It turns out that ~ is pretty much unused (binary negation is not that often called) in comparison to + or - for example, so there is little chance of confusion. Once you've settled on this, using it consistently gives it a new meaning to the tilde; like using operator<< and operator>> for streaming data has become a C++ idiom.
The ~ does nothing. Almost any other content inside those parentheses would work the same.
The lynchpin of this trick is to test whether _TRIGGER_PARENTHESIS_ is next to (~) in the expansion of _TRIGGER_PARENTHESIS_ __VA_ARGS__ (~). Either way, HAS_COMMA(...) expands its arguments to either 0 or 1.
The arguments to be tested is placed between the macro and its parenthesis, the macro only triggers if the arguments are empty:
_TRIGGER_PARENTHESIS_ __VA_ARGS__ (~)
NOTE: Actually the very link you posted states it. I will check for a reference to this in the standard.