This is the mail archive of the egcs@egcs.cygnus.com mailing list for the EGCS project. See the EGCS home page for more information.
In egcs, dynamic_cast seems to have behavior different from that
prescribed by the C++ standard. However, all other C++ compilers I've
tried do exactly the same thing as egcs, so I think that I'm probably
misunderstand the standard. If someone could clarify to me if and why
the standard actually prescribes egcs's behavior, I would appreciate
it.
Keep in mind that I don't actually like the way dynamic cast is
defined by the standard. However, this is a question about what what
the standard requires, not what it should have required. I'm trying
to write ANSI-compliant code and would like 'g++ -ansi' to reject or
warn about any violations of standard C++.
5.2.7.8 says of the run-time check done by dynamic_cast:
The run-time check logically executes as follows:
If, in the most derived object pointed (referred) to by v, v
points (refers) to a public base class sub object of a T object,
and if only one object of type T is derived from the sub-object
pointed (referred) to by v, the result is a pointer (an lvalue
referring) to that T object.
Otherwise, if v points (refers) to a public base class sub-object
of the most derived object, and the type of the most derived
object has an unambiguous public base class of type T, the result
is a pointer (an lvalue referring) to the T sub-object of the
most derived object.
Otherwise, the run-time check fails.
The code pasted below produces the following output:
bp is NULL
bigger:: bp is NULL
That means that in a method or friend of T, egcs allows a dynamic_cast
from a private base clase of T to T, but not from a private base class
of T to another private base class of T. Obviously if you are not in
a private base class of T, you cannot dynamic_cast to T. However, I
don't see any language in the standard suggesting that access to a
class's private members should allow otherwise prohibited
dynamic_casts. Thus, the output I would expect would be:
bp is NULL
bbp is NULL
bigger:: bp is NULL
bigger:: bbp is NULL
Since all compilers do seem to give special dynamic_casts powers to
friends and methods, and doing so must require additional
implementation work in the compiler, I'm willing to believe this is in
fact correct behavior. I wish I could understand why, however. And
if it's a bug in the egcs, obviously I'd like to see it fixed (this
should be easy to detect at compile time).
Any clues?
Thanks,
David
===
#include <stdio.h>
struct small {
virtual ~small () {}
};
struct big : public small {
friend void dyncast (small *);
};
struct bigger : private big {
big *getbig () { return this; }
void test () {
small *sp = this;
big *bp = dynamic_cast<big *> (sp);
if (!bp)
fprintf (stderr, "bigger:: bp is NULL\n");
bigger *bbp = dynamic_cast<bigger *> (sp);
if (!bbp)
fprintf (stderr, "bigger:: bbp is NULL\n");
}
friend void dyncast (small *);
};
void
dyncast (small *sp)
{
big *bp = dynamic_cast<big *> (sp);
if (!bp)
fprintf (stderr, "bp is NULL\n");
bigger *bbp = dynamic_cast<bigger *> (sp);
if (!bbp)
fprintf (stderr, "bbp is NULL\n");
}
int
main ()
{
bigger b;
dyncast (b.getbig ());
b.test ();
return 0;
}