I spent a whole day looking for a bug caused by wrongly passing Windows PHANDLE type to a function expecting HANDLE!!! I was expecting the VC++ 2010 compiler to catch such a simple and obvious type mismatch error. However, it didn’t. It just didn’t.
On a closer look, HANDLE is defined as void pointer in winnt.h and so PHANDLE is just void pointer pointer. Since anything can be passed to void * or void ** so PHANDLE and HANDLE mismatch can’t be warned by the compiler.
Is there anyway to avoid such a problem. I don’t know how many other Windows types are typedef’ed as void *. Are there any strategies to avoid such errors?
For example, the following compiled without any error in VC++ 2010, although the function is called by wrong pointer types. And, it is not obvious the pitfall is there unless one knows HANDLE (or any other Windows types) is a void pointer:
void f1 (HANDLE h) {
printf("%x",h);
}
int _tmain(int argc, _TCHAR* argv[])
{
PHANDLE ph=NULL;
int c=0;
f1(ph);
f1(&c);
return 0;
}
The way to think of
HANDLEis as the base type for all handles, such asHWND,HDCetc. Because C doesn’t support the concept of a base type they had to make it avoid*.In most cases your app should be compiled with the
STRICTflag set. This will ensure that all specific handles are actually based off of structures and so you won’t have any issues. However, if you do write a method that works with a generalHANDLEthen you’re going to have to be careful!