Note that there are some explanatory texts on larger screens.

plurals
  1. POPlease explain this hardcore macro that does casting and typechecking
    primarykey
    data
    text
    <p>The following code is from an existing application that has to be compiled in both C and C++. There's a macro:</p> <pre><code>/* 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) &amp;IID_##type, \ (void **)(void *)((obj) + (sizeof((obj)-(type **)(obj))) \ - (sizeof((obj)-(type **)(obj)))) </code></pre> <p>that is used as follows:</p> <pre><code>ISomeInterface *object; CoCreateInstance(&amp;CLSID_SomeInterfaceImpl, NULL, CLSCTX_INPROC_SERVER, COMPTR(ISomeInterface, &amp;object)))); </code></pre> <p>here the idea is that the last two parameters of <code>CoCreateInstance()</code> are <code>IID&amp;</code> and <code>void**</code> and that macro grabs <code>ISomeInterface**</code> and converts it to <code>IID&amp;</code> and <code>void**</code> at the same time enforcing a compile-time check that the address passed in place of <code>ISomeInterface**</code> is indeed an address of <code>ISomeInterface*</code> pointer variable.</p> <p>Okay, but what's the need for</p> <pre><code>((obj) + (sizeof((obj)-(type **)(obj))) \ - (sizeof((obj)-(type **)(obj))) </code></pre> <p>complex expression? I see that the type checking is enforced with <code>(obj)-(type**)(obj)</code> subexpression. What's the need for adding and then subtracting the <code>sizeof()</code>? And what's the need for casting to <code>void*</code> before casting to <code>void**</code>?</p> <p>I suppose the same can be done as follows:</p> <pre><code>#define COMPTR(type, obj) &amp;IID_##type, \ (void **)(sizeof((obj)-(type**)(obj)), obj) </code></pre> <p>here the first part of comma operator would contain a <code>sizeof()</code> 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 <code>void**</code>.</p> <p>What can the original macro do what the one I suggest can't? What's the need for those complications?</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

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