I need to remove the last trailing comma from a list of macro arguments (because they will be eventually expanded into template arguments where the trailing comma is not admitted).
So I need a macro remove_trailing_comma()
which called like remove_trailing_comma(arg1, arg2, arg3, )
expands to arg1, arg2, arg3
.
I've tried with different combinations of varargs and __VA_OPT__
but I seem to not be able to do it.
For example:
#define discard_trailing_comma(arg, ...) \
arg __VA_OPT__(,) discard_trailing_comma(__VA_ARGS__)
discard_trailing_comma(1, 2, 3, )
does not work (with g 10) because expands to 1 , discard_trailing_comma(2, 3,)
, I do not know why (are macro not expanded recursively?)
Is this possible in C 20?
CodePudding user response:
Assuming you have a bounded number of parameters, you could make a delegate function-like macro as a helper to choose the appropriate implementation macro.
#define GET_DTC(_1,_2,_3,_4,NAME,...) NAME
#define DTC4(_1,_2,_3,_4) _1,_2,_3
#define DTC3(_1,_2,_3) _1,_2
#define DTC2(_1,_2) _1
#define DTC1(_1)
#define discard_trailing_comma(...) \
GET_DTC(__VA_ARGS__, DTC4, DTC3, DTC2, DTC1)(__VA_ARGS__)
int arr[] = {
discard_trailing_comma(1, 2, 3, )
};
CodePudding user response:
gcc has a non-standard extension, ##__VA_ARGS__
, which should do the trick. It is documented here (search the page for ##__VA_ARGS__
).
Example usage (simplified to the bare minimum to make things easy on my tired eyeballs):
void call_me (int first, int second, int third) { }
#define EXPAND_ME(first, ...) call_me (first, ##__VA_ARGS__)
int main ()
{
EXPAND_ME (1, 2, 3);
}
Note that you need at one fixed argument, and this also works in Clang.
MSVC has a similar extension. If anyone's interested I'll add it here.