Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

dynamic_cast & Exceptions

1 view
Skip to first unread message

Al

unread,
Mar 4, 2007, 10:43:25 AM3/4/07
to
Hi,

Say we have:

class A {};
class B : public A {};

A* foo();

int main() {
dynamic_cast<B&>(*foo());
return 0;
}

Modulo any typos, this should work, assuming foo() returns what is
really a B*. Next, if foo() returns a different derived class of A*,
dynamic_cast is supposed to throw (since it's a reference).

However, what happens if:

i) foo() calls assert();
ii) foo() throws an exception.

Does the dynamic_cast exception override the user exception/assert?
Is it UB, or implementation-specific?

Thanks!
-Al.


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Ivan Novick

unread,
Mar 4, 2007, 1:53:38 PM3/4/07
to
On Mar 4, 7:43 am, Al <t...@haik.us> wrote:
> class A {};
> class B : public A {};
> A* foo();
> int main() {
> dynamic_cast<B&>(*foo());
> return 0;
> }
>
> However, what happens if:
>
> i) foo() calls assert();
> ii) foo() throws an exception.

Ok, if your assert macro calls abort...I would think the program would
terminate inside foo and never return.
If you throw an exception in foo, again I would think your
dynamic_cast would not be executed and the program would die because
of an uncaught exception.

In both cases, I can't see how the process would continue to process
your dynamic cast at all.

Ivan Novick
http://www.0x4849.net

Ulrich Eckhardt

unread,
Mar 5, 2007, 5:38:27 AM3/5/07
to
Al wrote:
> class A {};
> class B : public A {};
>
> A* foo();
>
> int main() {
> dynamic_cast<B&>(*foo());
> return 0;
> }
>
> Modulo any typos, this should work,

No: A does not have any virtual function, therefore it doesn't have any RTTI
and you can't dynamic_cast it. That's not your question though, and I'll
assume that it does e.g. have a virtual dtor or some other virtual
function.

> assuming foo() returns what is really a B*. Next, if foo() returns
> a different derived class of A*, dynamic_cast is supposed to throw
> (since it's a reference).

I don't agree with your idea of "works". The code is legal C++ (though maybe
not good C++) and even if it doesn't return a B it will work, just that
that means it will throw a std::bad_cast.

> However, what happens if:
>
> i) foo() calls assert();
> ii) foo() throws an exception.

In both cases, foo() doesn't return and the dynamic_cast is not evaluated.

> Does the dynamic_cast exception override the user exception/assert?

The dynamic_cast is not evaluated, so it doesn't come into effect.

> Is it UB, or implementation-specific?

Neither, both are well-defined. BTW: note that throwing an exception that is
not caught will terminate the program, but even if it was caught it
wouldn't change anything here.

Uli

--
Sator Laser GmbH
Geschäftsführer: Ronald Boers Steuernummer: 02/858/00757
Amtsgericht Hamburg HR B62 932 USt-Id.Nr.: DE183047360

James Kanze

unread,
Mar 5, 2007, 5:36:26 AM3/5/07
to
On Mar 4, 4:43 pm, Al <t...@haik.us> wrote:

> Say we have:

> class A {};
> class B : public A {};

> A* foo();

> int main() {
> dynamic_cast<B&>(*foo());
> return 0;
>
> }

> Modulo any typos, this should work, assuming foo() returns what is
> really a B*. Next, if foo() returns a different derived class of A*,
> dynamic_cast is supposed to throw (since it's a reference).

And since you don't catch the exception, the program aborts.

> However, what happens if:

> i) foo() calls assert();

If the assertion fails, the program aborts. Immediately.

> ii) foo() throws an exception.

The exception is thrown.

> Does the dynamic_cast exception override the user exception/assert?

If foo() throws an exception or aborts, the dynamic_cast never
gets executed. The results of foo() are an operand of the
dynamic_cast, and so must be available before dynamic_cast can
be executed.

> Is it UB, or implementation-specific?

Neither. It's all very specified.

--
James Kanze (GABI Software) email:james...@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

adrian....@gmail.com

unread,
Mar 5, 2007, 1:31:08 PM3/5/07
to
On Mar 5, 6:38 am, Ulrich Eckhardt <eckha...@satorlaser.com> wrote:
> Al wrote:
> > class A {};
> > class B : public A {};
>
> > A* foo();
>
> > int main() {
> > dynamic_cast<B&>(*foo());
> > return 0;
> > }
>
> > Modulo any typos, this should work,
>
> No: A does not have any virtual function, therefore it doesn't have any RTTI
> and you can't dynamic_cast it. That's not your question though, and I'll
> assume that it does e.g. have a virtual dtor or some other virtual
> function.

You're right Urlich, he would have to have at least a virtual
destructor which you would normally have if you are doing inheritance
anyway (except in very convoluted instances or when both of these
classes are really PODs).


Adrian


--

0 new messages