Re: Private inheritance interferes with dynamic cast
Marc wrote:
Hi all. Suppose we got something like this:
class A
{
//some code
};
class B: public SomeOtherClass, private A
{
//some more code
};
void foo (B* b)
{
A* a = dynamic_cast<A*> (b);
//a is NULL!?
}
When I use this code, dynamic_cast returns NULL. However, if I change B to
be a public inheritance from A, then it works fine. So, it seems like the
kind of inheritance is affecting dynamic_cast in some way. My question is:
is this correct according the C++ standard, or is it a bug in my compiler?
...
Most likely - yes, but read on.
Note, that in this case you are using 'dynamic_cast' to perform an _upcast_, not
a downcast, i.e. the "magic" run-time properties of 'dynamic_cast' are not used
in this case. If not for the access problem, this cast could've been performed
by an ordinary compile-time cast (e.g. 'static_cast' or C-style cast). Of
course, because of the access restriction, 'static_cast' will be ill-formed in
this case ("will not compile"), while C-style cast will in fact do the cast.
(Although forceful C-style cast through private inheritance is never a good idea.)
Now, what about 'dynamic_cast'? If you read the specification of 'dynamic_cast'
in C++ standard, it is a bit ambiguous. On the one hand, it sounds like
'dynamic_cast' is supposed to behave exactly like 'static_cast' when used for
upcasts, meaning that your example is also ill-formed, should not even compile.
On the other hand, it might also be interpreted as the situation when
'dynamic_cast' should compile and fail at run-time, i.e. return null-pointer.
This ambiguity is recognized in a relatively recent defect report #665
http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#665
and the issue is still open.
Personally, I believe that the former interpretation is the intended one. And,
for example, Comeau Online agrees with me on that. g++ 3.4.4 also reports a
compile error. Apparently, your version of g++ prefers the latter. Maybe you
should stop using that pre-release...
--
Best regards,
Andrey Tarasevich