Gilad Naaman
Gilad Naaman

Reputation: 6550

Appending 0s to an incomplete macro parameter list

I have the following couple of C preprocessor macros that I use:

#define TAKE4(a1, a2, a3, a4, ...) a1, a2, a3, a4
#define FILL_PARAMS(...) TAKE4(__VA_ARGS__, 0, 0, 0, 0)

When calling FILL_PARAMS with 1, 2, or 3 parameters, the later (unspecified) are turned into 0s as expected, but when giving no arguments there's an error.

Is there a way to add support for no-parameters?

Clarification:
Currently the following uses are supported:

FILL_PARAMS(1)         // => 1, 0, 0, 0
FILL_PARAMS(1, 2)      // => 1, 2, 0, 0
FILL_PARAMS(1, 2, 3)   // => 1, 2, 3, 0

And I want to add support for the following edge case:

FILL_PARAMS()          // => 0, 0, 0, 0

Help will be welcome.

Upvotes: 7

Views: 63

Answers (2)

Leandros
Leandros

Reputation: 16825

You can achieve this in multiple ways, the most simple way is to use

FILL_PARAMS(0)

as the empty case.

Another, more complicated, and cumbersome to use way is to always have the comma following the last parameter:

#define TAKE4(a1, a2, a3, a4, ...) a1, a2, a3, a4
#define FILL_PARAMS(...) TAKE4(__VA_ARGS__ 0, 0, 0, 0)

/* called like: */
FILL_PARAMS()
FILL_PARAMS(1,)
FILL_PARAMS(1,2,)
FILL_PARAMS(1,2,3,)

Or by being a little creative with GCCs comma swallowing extension:

#define TAKE4(a1, a2, a3, a4, a5, ...) a2, a3, a4, a5
#define FILL_PARAMS(...) TAKE4(0, ##__VA_ARGS__, 0, 0, 0, 0)

Upvotes: 0

Gilad Naaman
Gilad Naaman

Reputation: 6550

Found a hack-ish solution:

#define TAKE4(a1, a2, a3, a4, ...) a1, a2, a3, a4
#define FILL_PARAMS(...) TAKE4( __VA_ARGS__ + 0, 0, 0, 0, 0)

That works with at-least the following test-cases.

int i = 120;
printf("%d\t%d\t%d\t%d\n", FILL_PARAMS());
printf("%d\t%d\t%d\t%d\n", FILL_PARAMS(i));
printf("%d\t%d\t%d\t%d\n", FILL_PARAMS(1));
printf("%d\t%d\t%d\t%d\n", FILL_PARAMS(1, 2));
printf("%d\t%d\t%d\t%d\n", FILL_PARAMS(1, 2, 3));
printf("%d\t%d\t%d\t%d\n", FILL_PARAMS(1, 2, 3, 4));
printf("%d\t%d\t%d\t%d\n", FILL_PARAMS(1, 2, 3, i));

Upvotes: 2

Related Questions