I have defined a clunky macro to give myself a reduced probability of making mistakes in a project with a large amount of unique logging situations...
#define BANG(...) {fprintf(stderr, "in %s(), ", __func__);\
fprintf(stderr, ##__VA_ARGS__);}
And I can call this quite successfully like this...
BANG("Something went wrong\n");
But the following (obviously) breaks in frightening ways...
if(emulatorExitCode == 1)
BANG("emulatorExitCode: %d (an error)\n", emulatorExitCode);
else
everythingIsWonderful = 1;
I know the reason of course, it's the semicolon I accidentally left on the end of the call to BANG();
That rogue semicolon causes the if/else construct to separate into two fragments, disassociated from eachother. Here's the compiler error...
main.c:74:3: error: ‘else’ without a previous ‘if’
So far so good, the workaround is to have -Wall -Werror -Wextra -Wpedantic
in my compiler arguments so I cannot accidentally cause a horrible mess of my logic.
And as long as I always leave out the semicolon on the end of the BANG() macro calls I'll be OK because the macro definition uses braces around the two fprintf();
calls. But I'm worried that other people maintaining my code later will not realise that this is a problem (it's really not obvious) and get in a mess.
Question
Can this macro #define
be rewritten to either reduce the danger posed by the problematic semicolon OR can it be rewritten to roll these two calls to fprintf into a single call? The latter is complicated by the fact that it's variadic AND has the famously head-scratchy printf
-family semantics to deal with.