I've just spent two days delivering my C Foundation course to the massively talented people at Cisco (nee Tandberg nee Codian) in Langley. One of the guys on the course called Alex showed me an amazing C99 macro that counts the number of parameters. The capacity of C to surprise me with something new never ceases to amaze. Here it is (cut down to handle just 6 parameters to save space):
#include <stdio.h>
#define PP_NARG(...) \
PP_NARG_(__VA_ARGS__, PP_RSEQ_N())
#define PP_NARG_(...) \
PP_ARG_N(__VA_ARGS__)
#define PP_ARG_N( \
_1, _2, _3, _4, _5, _6, N, ...) (N)
#define PP_RSEQ_N() \
6,5,4,3,2,1,0
int main(void)
{
printf("%d\n", PP_NARG(a,b+c+d)); // 2
printf("%d\n", PP_NARG(a,b,c,d,e+f)); // 5
return 0;
}
Alex mentioned it doesn't work for zero parameters - it incorrectly returns one. Of course I can't resist seeing if I can fix that. After playing around a bit I've come up with this which seems to work.
#define PP_NARG(...) \
PP_NARG_(sizeof #__VA_ARGS__, __VA_ARGS__, PP_RSEQ_N())
#define PP_NARG_(delta, ...) \
PP_ARG_N(delta, __VA_ARGS__)
#define PP_ARG_N( \
delta, _1, _2, _3, _4, _5, _6, N, ...) (N - ((delta)==1))
#define PP_RSEQ_N() \
6,5,4,3,2,1,0
Alex joked that at parties he's tried to impress girls with this macro. Of course he increases the number of parameters to 128. Size matters after all. And naturally he boasts not only of the macro's size but also of it capacity for expansion!