At a reply of a blog post of Raymond Chen,
A questioner pointed out
Raymond, I believe the C++ example is not correct since the position
of the base class subobject in the derived class is unspecified
according to ISO C++ 2003 Standard (10-3, page 168), and you assume
that the base class subobject is always at the beginning. The C
example would be fine in C++ too, so I'd stick with it.
Raymond replied
[The code does not make this assumption. That's why it's important to
use static_cast instead of reinterpret_cast. Try it: Add a virtual
method to OVERLAPPED (so a vtable goes in front) and observe what the
compiler does. -Raymond]
I could guess after read his comments. Using static_cast is fine at the example but reinterpret_cast is not. Because reinterpret_cast is not convert vtable. Do I understand it rightly?
Though, if I use C-Style cast at there(not reinterpret_cast), could it also go wrong?
I re-read More Effective C++'s cast explanation to understand that. But there was no answer about that.
Best Answer
No, the problem is that the
reinterpret_cast
is completely oblivious about the inheritance. It will simply return the same address unchanged1. Butstatic_cast
knows that you're performing a downcast: i.e. casting from a base class to a derived class. Since it knows both types involved it adjusts the address accordingly, i.e., does the right thing.Let's pretend our implementation lays out the hypothetical
OVERLAPPEDEX
class that has a virtual function like this:The pointer we're given points to the
OVERLAPPED
subobject.reinterpret_cast
would not change that. It would only change the type. Obviously, accessing theOVERLAPPEDEX
class through this address would easily wreak havoc, because the locations of its subobjects are all wrong now!static_cast
knows that to convert aOVERLAPPED*
toOVERLAPPEDEX*
it must adjust the address, and does the right thing:A C-style cast is defined as the first one of the following that succeeds:
const_cast
static_cast
static_cast
, thenconst_cast
reinterpret_cast
reinterpret_cast
, thenconst_cast
As you can see, a
static_cast
is tried beforereinterpret_cast
, so in this case, a C-style cast would also do the right thing.More info
1Not guaranteed. There are very little guarantees about what happens on a
reinterpret_cast
. All implementations I know of will simply give out the same address unchanged.