Tip 25: Variadic macros
20 November 11. [link]
PDF version
level: not hard
purpose: delightful tricks to follow in the coming week
Part of a series of tips on POSIX and C. Start from the tip intro page, or get 21st Century C, the book based on this series.
I broadly consider variable-length functions in C to be broken--I have a personal rules about the three forms I'm willing to use, which I'll maybe expound upon later.
But variable-length macro arguments are easy. The keyword is __VA_ARGS__, and it
expands to whatever set of elements were given.
For example, here's a fast way to implement a customized variant of printf for reporting errors:
#define print_a_warning(...) {\
printf("Glitch detected in %s at line %s:%i: ", __FUNCTION__, __FILE__, __LINE__); \
printf(__VA_ARGS__); }
//usage:
print_a_warning("x has value %g, but it should be between zero and one.\n", x);
The __FUNCTION__, __FILE__, and __LINE__ macros get filled in with
what you'd expect.
You can probably guess how the ellipsis (...) and __VA_ARGS__ work: whatever is between
the parens gets plugged in at the __VA_ARGS__ mark.
You can have arguments before the ellipsis if you want. A full example:
#define print_a_warning(dostop, ...) { \
printf("Glitch detected in %s at line %s:%i: ", __FUNCTION__, __FILE__, __LINE__);\
printf(__VA_ARGS__); \
if (dostop=='s') abort(); \
}
int main(int argc, char ** argv){
if (argc <= 1) print_a_warning('s', "argc has value %i, but it should be two. Halting. \n", argc);
if (argc > 2) print_a_warning('c', "argc has value %i, but it should be two. Using ony the first arg. \n", argc);
printf("arg one = %s\n", argv[1]);
}
[Previous entry: "Tip 24: Compound literals"]
[Next entry: "Tip 26: Safely terminated lists"]
