Is the result of valid dynamic cast always equal to the result ofcorrespondent static cast?

P

Pavel

Let us assume that A and B are classes, the variable aPtr has type A*,
and the code containing the following assert statement compiles without
error:

assert(!dynamic_cast<B*>(aPtr)
|| (dynamic_cast<B*>(aPtr) == static_cast<B*>(aPtr)));


Can A and B be defined in a way that the assertion would fail?

TIA,
-Pavel
 
M

Marcel Müller

Pavel said:
Let us assume that A and B are classes, the variable aPtr has type A*,
and the code containing the following assert statement compiles without
error:

assert(!dynamic_cast<B*>(aPtr)
|| (dynamic_cast<B*>(aPtr) == static_cast<B*>(aPtr)));


Can A and B be defined in a way that the assertion would fail?


AFAIK no, since the first condition checks whether a dynamic cast is
allowed.


Marcel
 
V

Vaclav Haisman

Pavel wrote, On 17.9.2010 13:33:
Let us assume that A and B are classes, the variable aPtr has type A*, and
the code containing the following assert statement compiles without error:

assert(!dynamic_cast<B*>(aPtr)
|| (dynamic_cast<B*>(aPtr) == static_cast<B*>(aPtr)));


Can A and B be defined in a way that the assertion would fail?
The following gives me false with codepad.org:

#include <iostream>

struct A
{
virtual ~A ()
{ }
};

struct C
{
virtual ~C ()
{ }
};

struct B : C, A
{ };

struct E : A
{ };

struct D : E, B
{ };

int
main ()
{
D d;
A * aPtr = static_cast<E *>(&d);
std::cout << (dynamic_cast<B*>(aPtr) == static_cast<B*>(aPtr));
}
 
M

Marcel Müller

Vaclav said:
The following gives me false with codepad.org:

#include <iostream>

struct A
{
virtual ~A ()
{ }
};

struct C
{
virtual ~C ()
{ }
};

struct B : C, A
{ };

struct E : A
{ };

struct D : E, B
{ };

int
main ()
{
D d;
A * aPtr = static_cast<E *>(&d);
std::cout << (dynamic_cast<B*>(aPtr) == static_cast<B*>(aPtr));
}

This code has undefined behavior. static_cast<B*>(aPtr) is invalid
because the instance of A in aPtr is not a superclass of type B. It is a
superclass of type E instead.

Of course, dynamic_cast does not fail on this cross cast.


Marcel
 
P

Pavel

Vaclav said:
Pavel wrote, On 17.9.2010 13:33:
The following gives me false with codepad.org:

#include<iostream>

struct A
{
virtual ~A ()
{ }
};

struct C
{
virtual ~C ()
{ }
};

struct B : C, A
{ };

struct E : A
{ };

struct D : E, B
{ };

int
main ()
{
D d;
A * aPtr = static_cast<E *>(&d);
std::cout<< (dynamic_cast<B*>(aPtr) == static_cast<B*>(aPtr));
}
Thanks so much Vaclav!

I felt something was fishy in that assumption in the code I was reading
but could not exactly understand what was that.

-Pavel
 
J

James Kanze

Let us assume that A and B are classes, the variable aPtr has type A*,
and the code containing the following assert statement compiles without
error:
assert(!dynamic_cast<B*>(aPtr)
|| (dynamic_cast<B*>(aPtr) == static_cast<B*>(aPtr)));
Can A and B be defined in a way that the assertion would fail?

I don't think so off hand, but it's certainly possible to define
the classes in such a way that the static_cast won't be legal
(although the dynamic_cast is).
 
V

Vaclav Haisman

Marcel Müller wrote, On 17.9.2010 22:39:
This code has undefined behavior. static_cast<B*>(aPtr) is invalid because
the instance of A in aPtr is not a superclass of type B. It is a superclass
of type E instead.

Of course, dynamic_cast does not fail on this cross cast.
I did not realise it was UB but it does make sense. Though that's maybe what
the assert is about, possibly detecting UB, however fragile/undefined it
might be.
 
P

Pavel

James said:
I don't think so off hand, but it's certainly possible to define
the classes in such a way that the static_cast won't be legal
(although the dynamic_cast is).
Thanks James! Vaclav gave a good example in his above post. I tend to
forget about a possibility to have more than one identical base class
because I don't use it often. I just remembered the code should not have
relied on the above condition in general but could not recall why.

-Pavel
 

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,734
Messages
2,569,441
Members
44,832
Latest member
GlennSmall

Latest Threads

Top