What harsh examples show that C-style castings are bad?

I recently found a great example of why C-style is different. We start with the following class that implements several COM interfaces (I have two for brevity, but there may be ten in real life):

class CMyClassInitial : public IInterface1, public IInterface2 { //declarations omitted }; HRESULT CMyClassInitial::QueryInterface(REFIID iid, void** ppv) { if( ppv == 0 ) { return E_POINTER; } *ppv = 0; if( iid == __uuidof(IUnknown) || iid == __uuidof(IInterface1) ) { *ppv = (IInterface1*)this; } else if( iid == __uuidof(IInterface2) ) { *ppv = (IInterface2*)this; } else { return E_NOINTERFACE; } AddRef(); return S_OK; } 

The above implementation uses C-cast for adjustment pointers to account for multiple inheritance . They even work as static_cast - this pointer value will be correctly adjusted.

Now we copy-paste (or should I use the retry code?) The same implementation of QueryInterface() in some other very similar class.

 class CMyClassModified : public IInterface1 { //declarations omitted }; 

and leave the implementation the same. The new class is no longer inherited from IInterface2 , but

 } else if( iid == __uuidof(IInterface2) ) { *ppv = (IInterface2*)this; } 

will compile just fine, and the C-style will act like reinterpret_cast - this pointer value will be copied unchanged. The caller receives a pointer to an object that IInterface2 does not actually implement - a direct way of undefined behavior. Such problems are difficult to detect in a huge database and when there are many (not two, as in my example) interfaces.

If static_cast used, which would not be, the compiler would throw an error trying to compile

 *ppv = static_cast<IInterface2*>(this); 

IMO, which is a pretty harsh example of how using a C-style cast can cause serious problems.

What other examples?

+5
c ++ casting
source share
2 answers

This frequently asked question summarizes everything about why c-casts are bad.

Any c-cast is the bomb's potentiality, as they hide warnings and conversion errors, silencing the compiler.

Since you need an example, here it is:

 int main() { float a = 0.123; double *b = ( double* ) &a; *b = 0.123; } 
+2
source share

A very simple example:

 class ClassB;//only forward declaration, no real declaration included Class A * a; Class B * b; a = (ClassA *)b; 

Actuation will always be flawlessly successful, if only a declaration of the ClassB class. It doesn't matter if ClassB is derived from ClassA. And it will also be an error if ClassB is not only derived from ClassA:

 class ClassB:public SomeOtherClass, public ClassA {}; 
+1
source share

All Articles