Jeff M
Jeff M

Reputation: 2573

IID_PPV_ARGS and Dereferencing NULL

A project I'm working on and some MSDN documentation has code such as this:

IFileOpenDialog *pFileOpen;
IID_PPV_ARGS(&pFileOpen)

Where IID_PPV_ARGS is:

#define IID_PPV_ARGS(ppType) __uuidof(**(ppType)), IID_PPV_ARGS_Helper(ppType)

My question is about the **(ppType) part. Wouldn't this end up dereferencing a null or unitialized pointer? Why does this work?

Upvotes: 4

Views: 2747

Answers (2)

United_Stomach
United_Stomach

Reputation: 21

One more point for Jonathan's answer (as I cannot leave a comment due to my reputation is too low):

In the debug build, __uuidof always initializes an object dynamically (at runtime). In a release build, __uuidof can statically (at compile time) initialize an object.

See: https://learn.microsoft.com/en-us/cpp/cpp/uuidof-operator?view=msvc-160

Upvotes: 2

Jonathan Potter
Jonathan Potter

Reputation: 37192

__uuidof() is a proprietary Microsoft extension, that the compiler knows how to deal with. It's evaluated at compile time, not at run time.

The compiler attempts to look up and substitute the UUID for the given interface. The interface declares its UUID using the __declspec(uuid("...")) extension. If the compiler can't find the UUID, the build will fail. No pointers are actually dereferenced at run time.

ppType is set to a IFileOpenDialog**, thus *(ppType) is a IFileOpenDialog* and **(ppType) is a IFileOpenDialog. As such, __uuidof(**(ppType)) is evaluated as __uuidof(IFileOpenDialog) at compile time.

It's the same as doing this:

char* ptr = nullptr;
size_t charSize = sizeof(*ptr);

sizeof(*ptr) will be evaluated as sizeof(char) at compile time, even though ptr is null.

Upvotes: 11

Related Questions