Private inheritance interferes with dynamic cast

M

Marc

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?
I'm using a pre-release version of g++ 3.3 (I know I shouldn't be using it,
but it's a long, non-related story).
 
B

Bo Persson

Marc said:
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?

It is all correct. A is a private subobject of B, so you cannot access
it.


Bo Persson
 
T

tragomaskhalos

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?
I'm using a pre-release version of g++ 3.3 (I know I shouldn't be using it,
but it's a long, non-related story).

class B : public A ... means "B IS-A A"
class B : private A ... means "B is implemented in terms of A"

So, since B is not an A, dynamic_cast returns null as expected.
 
A

Andrey Tarasevich

Marc said:
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...
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top