I have zillions of my_printf() function calls in a huge program. I now want to convert them all so that the function takes a new integer argument (call it x) without having to edit the zillions of calls. If my_printf only ever took exactly one string argument then I could do something like this:
#define my_printf(str) _my_printf(x,str)
void _my_printf(int x,char *str) // changed from my_printf(char *str)
{
// stuff
}
But as my_printf takes a variable number of arguments I'm not sure how to do it. Can it be done?
EDIT: for those wondering why I should want to do such a thing, here's a related example:
#if BELT_AND_BRACES_DIAGNOSTIC_MODE
#define function(x) _function(__FILE__,__LINE__,x)
#else // speed critical optimised mode
#define function(x) _function(x)
#endif
#if BELT_AND_BRACES_DIAGNOSTIC_MODE
void _function(char *file,int line,int x)
#else
void _function(int x)
#endif
{
// stuff
#if BELT_AND_BRACES_DIAGNOSTIC_MODE
if (something_went_wrong)
{
printf("Cock up in function when called from %s line %d\n",file,line);
}
#endif
}
You may use C99 variadic macros:
#define my_printf(...) my_printf_(x, __VA_ARGS__)
As Microsoft's implementation suppresse trailing commas, the str
argument can be added explicitly
#define my_printf(str, ...) my_printf_(x, str, __VA_ARGS__)
but this would lead to a syntax error in standard C when invoked without variadic arguments
my_printf("foo")
or an empty argument list
my_printf("foo",)
Therefore, I'd go with the first version.
If the code can be compiled as C99 code, you can define a variadic macro
#define my_printf(str, args...) _my_printf(x, str, ##__VA_ARGS__)
The preprocessor will replace the arguments ... and the GNU preprocessor will remove the trailing comma in case the macro is invoked only with the str argument.
The best thing is of course to bite the bullet and edit the code. Otherwise you're creating a "mystery", that needs to be solved by all future maintainers of the code. Even if that's only you, this is exactly the kind of clever trick that you will forget all about. It sucks to come back, and be puzzled by strange pointless-seeming macros.
That said, if you're using a GNU toolchain, you can perhaps look into using varargs macros.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With