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?
The static_cast operator converts a null pointer value to the null pointer value of the destination type.
The static_cast operator converts variable j to type float . This allows the compiler to generate a division with an answer of type float . All static_cast operators resolve at compile time and do not remove any const or volatile modifiers.
You can static_cast a null pointer - it will give you a null pointer.
The cast is done at run time and can fail if the underlying object does not support the target interface. If a static_cast fails, then the code does not compile (an error is issued: E2031).
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".
No. If the pointer refers to a valid object, and the conversion is valid, then the result will also refer to a valid object, so it won't be null. If either is invalid, then the code is incorrect and the result is undefined. So the only way for valid usage to give a null result is to start with null.
In the specific case of converting between object pointers and void pointers, the standard has this to say (5.2.9/10):
A value of type "pointer to object" converted to "pointer to
void
" and back to the original pointer type will have its original value.
and this (4.10/3)
The result of converting a "pointer to T" to a "pointer to
void
" points to the start of the storage location where the object of type T resides
so the original and final object pointers will be the same, and the void
pointer will be null if and only if the object pointers are.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With