以下代码来自必须同时使用 C 和 C++ 编译的现有应用程序。有一个宏:
/* 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))))
用法如下:
ISomeInterface *object;
CoCreateInstance(&CLSID_SomeInterfaceImpl, NULL,
CLSCTX_INPROC_SERVER, COMPTR(ISomeInterface, &object))));
这里的想法是 CoCreateInstance()
的最后两个参数是 IID&
和 void**
并且那个宏抓取 ISomeInterface**
并将其转换为 IID&
和 void**
同时强制执行编译时检查是否传递的地址代替了 ISomeInterface**
确实是ISomeInterface*
指针变量的地址。
好的,但是有什么需要
((obj) + (sizeof((obj)-(type **)(obj))) \
- (sizeof((obj)-(type **)(obj)))
复杂的表达?我看到类型检查是使用 (obj)-(type**)(obj)
子表达式强制执行的。 sizeof()
加减需要什么?在转换为 void**
之前转换为 void*
有什么必要?
我想同样可以按如下方式完成:
#define COMPTR(type, obj) &IID_##type, \
(void **)(sizeof((obj)-(type**)(obj)), obj)
此处逗号运算符的第一部分将包含一个 sizeof()
,它将强制执行类型检查并计算为常量,第二部分将只产生相同的指针,并且该指针将被转换为无效**
。
原始宏可以做什么我建议的不能做的事情?那些并发症有什么必要?
最佳答案
也许原作者不知道逗号运算符?这在 C/C++ 程序员中并非闻所未闻。
关于c++ - 请解释这个执行强制转换和类型检查的硬核宏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6519145/