Can static_cast turn a non-null pointer into a null pointer?

I need to write code for the callback function (it will be called from ATL, but this is not very important):

HRESULT callback( void* myObjectVoid ) { if( myObjectVoid == 0 ) { return E_POINTER; } CMyClass* myObject = static_cast<CMyClass*>( myObjectVoid ); return myObject->CallMethod(); } 

here void* guaranteed to be a pointer to CMyClass , so static_cast is legal. My concern is that the code should be as portable as possible (to later versions of Visual C ++). Therefore, to be a superparanoid, I tend to also check the CMyClass* pointer - 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 turn a non-null pointer into a null pointer?

+6
c ++ pointers visual-c ++ static-cast
source share
4 answers

static_cast can change the value of the pointer if you drop between parts of an object at 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 value of the null pointer (4.10) is converted to the value of the null pointer (5.2.9-8), that is, if c NULL , then b also NULL (and not adjusted), and therefore c2 set to NULL . Thing means: if myObjectVoid NULL static casting myObjectVoid yields NULL , then the value of myObjectVoid was obtained bypassing the type system somehow. And this means that the compiler can reset your second check because "it still cannot happen."

+7
source share

Not. 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 will not be zero. If this is not true, the code is incorrect and the result is undefined. Thus, the only way for proper use is to give a null result - start from scratch.

In the specific case of conversion of object pointers and void pointers, the standard says (5.2.9 / 10):

A value of type "pointer to an object", converted to a "pointer to void " and back to the original type of pointer, will have its original value.

and this (4.10 / 3)

The result of converting a "pointer to T" to a "pointer to void " indicates the beginning of the storage location where an object of type T is located

therefore, the source and destination pointers of objects will be the same, and the void pointer will be null if and only if the pointers of objects.

+5
source share

The only static_cast change should point to a word alignment pointer. So, theoretically, myObjectVoid points to the last byte in memory, it is possible that it can be "aligned" to 0, but I do not see a real problem in this.

0
source share

No, the second check is not reasonable. It is not possible for static_cast turn a non-null pointer into a null pointer. The only thing that static_cast can change relative to the set value in your case (as a pointer) is to configure the address. Otherwise, it is strictly related to advising the rest of the analysis of the type of compiler that the result of the expression should be considered as the target type. For a pointer, this means that dereferencing finds the correct address in the target, and the steps with increment and decrement steps correspond to the type size.

0
source share

All Articles