I think what it gives you, is that the user of the macro can pass in a pointer of any old type, not just Result*
. Personally I'd either do it your way, or if I really wanted to allow (for example) a void*
macro argument I'd write *(Result*)(result) = callResult;
.
There's another thing it might be, depending what the rest of the macro looks like. Does "some additional processing" mention resultVar
at all, or is the line (*resultVar) = callResult;
conditional? If so, then resultVar
exists in order to ensure that the macro evaluates each of its arguments exactly once, and therefore behaves more like a function call than it would if it evaluated them any other number of times (including zero).
So, if you call it in a loop like HANDLE_CALL(output++, *input++)
then it does something vaguely predictable. At least, it does provided that output
is a Result*
as the macro author intended. I'm still not sure what the cast gives you, other than allowing different argument types like void*
or char*
.
There are some situations where it could make another difference whether you have that extra cast or not. For example, consider:
typedef double Result;
int foo() { return 1; }
int i;
HANDLE_CALL(&i, foo());
if typedef double Result;
isn't visible on screen, the other three lines appear pretty innocuous. What's wrong with assigning an int to an int, right? But once the macro is expanded, bad stuff happens when you cast an int*
to double*
. With the cast, that bad stuff is undefined behavior, most likely double
is bigger than int
and it overruns the memory for i
. If you're lucky, you'll get a compiler warning about "strict aliasing".
Without the cast you can't do double* resultVar = &i;
, so the original macro with that change catches the error and rejects the code, instead of doing something nasty. Your version with *result = callResult;
actually works, provided that double
can accurately represent every value of int
. Which with an IEEE double and an int
smaller than 53 bits, it can.
Presumably Result
is really a struct, and nobody would really write the code I give above. But I think it serves as an example why macros always end up being more fiddly than you think.