c++ - 请解释这个执行强制转换和类型检查的硬核宏

标签 c++ c macros types casting

以下代码来自必须同时使用 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/

相关文章:

c++ - 无法为 double 赋值

C++,接受后无法接收数据和无效套接字

c++ - 在类定义中定义线程池的无法解释的语法错误

c - GCC C编译器警告 "warning: control reaches..."

java - JNI -- native 方法上的 UnsatisfiedLinkError

c++ - 在编译时获取 std::variant 类型

C:删除数组中的元素并使先前的指针起作用

c++ - 如何找出 cl.exe 的内置宏

latex - 我可以将LaTeX宏 'return'设为文件名吗?

c++ - 如何避免 C++ 派生类中基类成员的重复拷贝