Suppose that, in C, I have an list of things specified using X-macros. For example,
#define TYPES(X, ...) \
X(__VA_ARGS__, i, int) \
X(__VA_ARGS__, j, unsigned int) \
X(__VA_ARGS__, l, long) \
X(__VA_ARGS__, m, unsigned long)
If I add a second copy of that macro (call it TYPES_
), it’s not hard to generate some code for each pair of things in the list; for example:
#define TYPES_(X, ...) \
X(__VA_ARGS__, i, int) \
X(__VA_ARGS__, j, unsigned int) \
X(__VA_ARGS__, l, long) \
X(__VA_ARGS__, m, unsigned long)
#define CAST(FROMCH, FROMTY, TOCH, TOTY) \
TOTY FROMCH ## to ## TOCH (FROMTY x) { return (TOTY)x; }
TYPES_(TYPES, CAST)
However, if I use TYPES
instead of the duplicate TYPES_
, this code won’t work, because (I think?) the top-level expansion TYPES
then contains an occurrence of TYPES
itself, which is not permitted to expand further.
Is there a way to convince the C preprocessor to generate code for a cartesian product of a list with itself, like here, without specifying the list twice? It’s probably possible with chaos/order-pp-style insanity that accomplishes a lot of expansions through billion laughs-like hacks, but I’d prefer not to resort to that.
You can use an EXPAND
macro to perform delayed expansion. Rather clumsily:
#define EXPAND(X) X
#define TYPES1() TYPES
#define TYPES2(...) TYPES1 EXPAND(())(__VA_ARGS__)
EXPAND(TYPES(TYPES2, CAST))
Demo.