Re: dynamic_cast
Francis Glassborow wrote:
Daniel Kr?gler wrote:
On 20 Nov., 19:01, "Alexander Arhipenko" <arhip...@gmail.com> wrote:
Part 1.
Suppose we have 2 classes:
struct A
{};
struct B : private A
{};
Should following dynamic_cast expression compile or return 0
pointer: B b;
A* pa = dynamic_cast<A*>(&b);
I think your question is a good one and my answer might be a
little bit like slipping on thin ice. My current interpretation
is that the standard's actually requires this expression to be
ill-formed and I try to reason why I think so - I hope that
others will add their own thoughts. To introduce, my reasoning
bases on the complete [expr.dynamic.cast] section and [conv.ptr]/3,
so maybe I have overlooked something.
I think you are mistaken. dynamic_cast is an execution time action
which includes cross-casting. As such a dynamic_cast is always well
formed. Surprised?
Yes.
By your description, this program is well-formed:
int main()
{
int i = 42;
return dynamic_cast<char&>(i);
}
I can't believe that that was the intention when writing the standard.
But I admit that clause [expr.dynamic.cast] has too many if-statements
without a clear indication which of those statements are mutually
exclusive. Even when reading the paragraphs strictly from top to
bottom, it is not unambiguously clear which paragraphs form a mutually
exclusive set of options.
But even then, I can't find a single condition in [expr.dynamic.cast]
that the expression in the example above fulfils.
Given
struct A {}
struct B {}
bool foo(A* a_ptr){
B* b_ptr(dynamic_cast<B*> a_ptr);
This cast can never succeed, because A and B are unrelated types, and A
is not a polymorphic type.
As A is not polymorphic, the compiler is not required to keep runtime
information about class A and the runtime check can't determine what
the most-derived type of a_ptr is.
....
}
The compiler cannot know that somewhere a programmer will write:
struct C: A, B {}
Now sonsider the code:
void bar(C c_ptr){
bool test( foo(c_ptr) );
....
}
The call to foo() is well formed and the dynamic_cast will succeed.
After struct A has been changed to be a polymorphic type, yes.
Now add into the mix that private is a compile time feature which is
not, IIRC, available during execution and the result is that not only
is the original code well-formed but should return a pointer to the A
base class.
For the check performed by dynamic_cast<>, it must be known if
public/non-public inheritance was used.
The check may only succeed if public inheritance was used (for both
types in case of a cross-cast).
As this is an awkward corner of the language and I do not have me
references to hand I could well be mistaken because I am working from
memory of decisions made more than a decade ago.
My feeling is that we have stumbled into a defect.
The semantic description of dynamic_cast<> contains a mixture of
conditions that can either be checked at compile-time or at runtime.
And it is not clear which of these conditions form a single, coherent,
mutually exclusive set.
I think that the clause could do with some restructuring, to make it
more clear which conditions belong together and which stand on their
own.
Bart v Ingen Schenau
--
a.c.l.l.c-c++ FAQ: http://www.comeaucomputing.com/learn/faq
c.l.c FAQ: http://c-faq.com/
c.l.c++ FAQ: http://www.parashift.com/c++-faq-lite/
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]