Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Please explain this hardcore macro that does casting and typechecking

The following code is from an existing application that has to be compiled in both C and C++. There's a macro:

/* Type-checking macro to provide arguments for CoCreateInstance() etc.
 * The pointer arithmetic is a compile-time pointer type check that 'obj'
 * really is a 'type **', but is intended to have no effect at runtime. */
#define COMPTR(type, obj) &IID_##type, \
(void **)(void *)((obj) + (sizeof((obj)-(type **)(obj))) \
                - (sizeof((obj)-(type **)(obj))))

that is used as follows:

ISomeInterface *object;
CoCreateInstance(&CLSID_SomeInterfaceImpl, NULL,
     CLSCTX_INPROC_SERVER, COMPTR(ISomeInterface, &object))));

here the idea is that the last two parameters of CoCreateInstance() are IID& and void** and that macro grabs ISomeInterface** and converts it to IID& and void** at the same time enforcing a compile-time check that the address passed in place of ISomeInterface** is indeed an address of ISomeInterface* pointer variable.

Okay, but what's the need for

((obj) + (sizeof((obj)-(type **)(obj))) \
     - (sizeof((obj)-(type **)(obj)))

complex expression? I see that the type checking is enforced with (obj)-(type**)(obj) subexpression. What's the need for adding and then subtracting the sizeof()? And what's the need for casting to void* before casting to void**?

I suppose the same can be done as follows:

#define COMPTR(type, obj) &IID_##type, \
(void **)(sizeof((obj)-(type**)(obj)), obj)

here the first part of comma operator would contain a sizeof() that would enforce the typecheck and evaluate to a constant, the second part would just yield the same pointer and the pointer would be cast to void**.

What can the original macro do what the one I suggest can't? What's the need for those complications?

like image 788
sharptooth Avatar asked Jun 29 '11 10:06

sharptooth


1 Answers

Maybe the original author wasn't aware of the comma operator? This is not exactly unheard of among C/C++ programmers.

like image 74
themel Avatar answered Oct 26 '22 05:10

themel