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 {
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?
c ++ casting
sharptooth
source share