I need to write code for a callback function (it will be called from within ATL, but that's not really important):
HRESULT callback( void* myObjectVoid )
{
if( myObjectVoid == 0 ) {
return E_POINTER;
}
CMyClass* myObject = static_cast<CMyClass*>( myObjectVoid );
return myObject->CallMethod();
}
here the void*
is guaranteed to be a pointer to CMyClass
, so static_cast
is legal. My concern is the code must be as portable (to newer versions of Visual C++ at least) as possible. So to be super-paranoic I'm inclined to check the CMyClass*
pointer as well - I mean what if it turns out to be null?
if( myObjectVoid == 0 ) {
return E_POINTER;
}
CMyClass* myObject = static_cast<CMyClass*>( myObjectVoid );
if( myObject == 0 ) {
return E_POINTER;
}
Is the second check reasonable? Is it possible for static_cast
to turn a non-null pointer into a null pointer?
static_cast can change the pointer value, if you cast between object parts on different offsets:
class A{ int x; }; class B{ int y; };
class C : A,B {};
C *c=new C();
B *b=c;
// The B part comes after the A part in C. Pointer adjusted
C *c2=static_cast<C*>(b);
// Pointer gets adjusted back, points to the beginning of the C part
However, "The null pointer value (4.10) is converted to the null pointer value of the
destination type." (5.2.9-8), i.e. if c
is NULL
, then b
is also NULL
(and not adjusted) and thus c2
is set to NULL
. The whole thing means: if static casting a non-NULL myObjectVoid
yields NULL
, then the value of myObjectVoid
was obtained by circumventing the type system somehow. And it means, that the compiler might throw your second check away because "it can't happen anyway".