Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>Maybe the original author wasn't aware of function templates. This macro is begging to be replaced by a function template.</p> <p>Apparently the fourth argument to <code>CoCreateInstance</code> is a pointer to some global object of type IID that pertains to the <code>type</code> (type argument to COMPTR) at hand. The fifth and final argument to <code>CoCreateInstance</code> is supposed to be a <code>type**</code> pointer.</p> <p>Instead, the function <code>CoCreateInstance</code> takes a <code>void**</code> (yech!) pointer as its last argument, obtained by casting the supposed <code>type**</code> pointer. The cast goes through <code>void*</code> as an intermediary because any pointer can be cast to/from a void* pointer.</p> <p>Sans the protection in that COMPTR macro, one could pass a <code>double*</code> pointer, or even a <code>long long</code> (not a pointer!) as the fifth argument to <code>CoCreateInstance</code>. Of course, this whole mess would have been avoided had the original author used C++ what its very good at, type safety. Instead he/she decided to go the void* pointer route and put the protection in the macro.</p> <p>What the goofiness is doing: The argument to <code>sizeof</code> is the pointer difference expression <code>(obj)-(type**)(obj)</code>. If <code>obj</code> is a <code>type**</code> pointer, this is 0 (as type ptrdiff_t). If <code>obj</code> is something else, this pointer difference expression is ill-formed. So, two cases, <code>obj</code> is a <code>type**</code> pointer, or it isn't.</p> <p>Case 1, <code>obj</code> is a <code>type**</code> pointer: The pointer difference expression is valid, so the last argument to <code>CoCreateInstance</code> expands to <code>(void**)(void*)(obj+8-8)</code>, assuming a 64 bit machine. (The +8-8 becomes +4-4 on a 32 bit machine.) Regardless of machine size, the offset is added and subtracted, leaving the original pointer.</p> <p>Case 2, <code>obj</code> is not a <code>type**</code> pointer: The pointer difference expression is ill-formed, so the code doesn't compile.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload