IID_PPV_ARGS 和取消引用 NULL
IID_PPV_ARGS and Dereferencing NULL
我正在做的一个项目 MSDN documentation 有这样的代码:
IFileOpenDialog *pFileOpen;
IID_PPV_ARGS(&pFileOpen)
其中 IID_PPV_ARGS 是:
#define IID_PPV_ARGS(ppType) __uuidof(**(ppType)), IID_PPV_ARGS_Helper(ppType)
我的问题是关于 **(ppType)
部分的。这不会最终取消对空指针或未初始化指针的引用吗?为什么这样做有效?
__uuidof()
是专有的 Microsoft 扩展,编译器知道如何处理。它是在编译时评估的,而不是在 运行 时间。
编译器尝试查找并替换给定接口的 UUID。该接口使用 __declspec(uuid("..."))
扩展声明其 UUID。如果编译器找不到 UUID,构建将失败。在 运行 时间实际上没有指针被取消引用。
ppType
设置为 IFileOpenDialog**
,因此 *(ppType)
是 IFileOpenDialog*
,**(ppType)
是 IFileOpenDialog
。因此,__uuidof(**(ppType))
在编译时被评估为 __uuidof(IFileOpenDialog)
。
这样做是一样的:
char* ptr = nullptr;
size_t charSize = sizeof(*ptr);
sizeof(*ptr)
在编译时将被评估为 sizeof(char)
,即使 ptr
为空。
Jonathan 的回答加一分(因为我的声誉太低无法发表评论):
在调试版本中,__uuidof
总是 动态初始化一个对象(在运行时)。在发布版本中,__uuidof 可以静态(在编译时)初始化一个对象。
参见:https://docs.microsoft.com/en-us/cpp/cpp/uuidof-operator?view=msvc-160
我正在做的一个项目 MSDN documentation 有这样的代码:
IFileOpenDialog *pFileOpen;
IID_PPV_ARGS(&pFileOpen)
其中 IID_PPV_ARGS 是:
#define IID_PPV_ARGS(ppType) __uuidof(**(ppType)), IID_PPV_ARGS_Helper(ppType)
我的问题是关于 **(ppType)
部分的。这不会最终取消对空指针或未初始化指针的引用吗?为什么这样做有效?
__uuidof()
是专有的 Microsoft 扩展,编译器知道如何处理。它是在编译时评估的,而不是在 运行 时间。
编译器尝试查找并替换给定接口的 UUID。该接口使用 __declspec(uuid("..."))
扩展声明其 UUID。如果编译器找不到 UUID,构建将失败。在 运行 时间实际上没有指针被取消引用。
ppType
设置为 IFileOpenDialog**
,因此 *(ppType)
是 IFileOpenDialog*
,**(ppType)
是 IFileOpenDialog
。因此,__uuidof(**(ppType))
在编译时被评估为 __uuidof(IFileOpenDialog)
。
这样做是一样的:
char* ptr = nullptr;
size_t charSize = sizeof(*ptr);
sizeof(*ptr)
在编译时将被评估为 sizeof(char)
,即使 ptr
为空。
Jonathan 的回答加一分(因为我的声誉太低无法发表评论):
在调试版本中,__uuidof
总是 动态初始化一个对象(在运行时)。在发布版本中,__uuidof 可以静态(在编译时)初始化一个对象。
参见:https://docs.microsoft.com/en-us/cpp/cpp/uuidof-operator?view=msvc-160