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

bad_cast exception 2

31 views
Skip to first unread message

Doug Mika

unread,
Jul 16, 2015, 10:03:00 PM7/16/15
to
Why is the following a compile time error and not a bad_cast exception:

// bad_cast example
#include <iostream> // std::cout
#include <typeinfo> // std::bad_cast

class Base {virtual void member(){}};
class Derived : Base {};

int main () {
try
{
Base b;
Derived rd = dynamic_cast<Derived>(b);
}
catch (std::bad_cast& bc)
{
std::cerr << "bad_cast caught: " << bc.what() << '\n';
}
return 0;
}

I should mention that it IS a bad_cast exception if I include ampersands (&) in

Derived& rd = dynamic_cast<Derived&>(b);

but why?

Paavo Helde

unread,
Jul 17, 2015, 2:56:49 AM7/17/15
to
Doug Mika <doug...@gmail.com> wrote in
news:3fdf48c9-3735-4d8a...@googlegroups.com:

> Why is the following a compile time error and not a bad_cast
> exception:

Because dynamic_cast is defined to work only on pointers and references.

>
> // bad_cast example
> #include <iostream> // std::cout
> #include <typeinfo> // std::bad_cast
>
> class Base {virtual void member(){}};
> class Derived : Base {};
>
> int main () {
> try
> {
> Base b;
> Derived rd = dynamic_cast<Derived>(b);
> }
> catch (std::bad_cast& bc)
> {
> std::cerr << "bad_cast caught: " << bc.what() << '\n';
> }
> return 0;
> }
>
> I should mention that it IS a bad_cast exception if I include
> ampersands (&) in
>
> Derived& rd = dynamic_cast<Derived&>(b);
>
> but why?

Because dynamic_cast is defined to work only on pointers and references.

Öö Tiib

unread,
Jul 17, 2015, 2:59:19 AM7/17/15
to
Because of syntax error that is diagnosed compile time.
There in 'dynamic_cast<T>(x)' that 'T' is required to be pointer to
complete type, reference to complete type or pointer to void and
'Derived' is neither of those so compiler can't parse what you want.

Doug Mika

unread,
Jul 17, 2015, 11:45:32 AM7/17/15
to
So in the example that compiles, with ampersands, (I include the example again below) why doesn't it simply return rd=nullptr, why does it throw an exception. My question I guess is, when does dynamic cast throw an exception and when does it return nullptr?

// bad_cast example
#include <iostream> // std::cout
#include <typeinfo> // std::bad_cast

class Base {virtual void member(){}};
class Derived : Base {};

int main () {
try
{
Base b;
Derived& rd = dynamic_cast<Derived&>(b);
}

K. Frank

unread,
Jul 17, 2015, 12:09:04 PM7/17/15
to
Hi Doug!

See my comment, inline below:

On Friday, July 17, 2015 at 11:45:32 AM UTC-4, Doug Mika wrote:
> On Thursday, July 16, 2015 at 9:03:00 PM UTC-5, Doug Mika wrote:
> > Why is the following a compile time error and not a bad_cast exception:
> > ...
>
> So in the example that compiles, with ampersands, (I include the example again below) why doesn't it simply return rd=nullptr, why does it throw an exception.

Because you are casting to a reference, not a pointer,
so it can't return a nullptr.

> My question I guess is, when does dynamic cast throw an exception and when does it return nullptr?

The short answer is because that's how dynamic_cast is
designed to work. But the reason is that references can't
be nullptrs so there is no "singular value" for the reference
version of dynamic_cast to return to signal the "bad cast"
error condition. Hence it is designed to throw an exception.

> // bad_cast example
> #include <iostream> // std::cout
> #include <typeinfo> // std::bad_cast
>
> class Base {virtual void member(){}};
> class Derived : Base {};
>
> int main () {
> try
> {
> Base b;
> Derived& rd = dynamic_cast<Derived&>(b);

rd is a reference, so can't be a nullptr. The
dynamic_cast<SomeType&> returns a reference type,
and can't return a nullptr (because nullptr is
a pointer type, not a reference type).

> }

...


Good luck.


K. Frank

Paavo Helde

unread,
Jul 17, 2015, 12:09:37 PM7/17/15
to
Doug Mika <doug...@gmail.com> wrote in
news:1fe677bb-bae0-4ef3...@googlegroups.com:

> On Thursday, July 16, 2015 at 9:03:00 PM UTC-5, Doug Mika wrote:
>> Why is the following a compile time error and not a bad_cast
>> exception:
>>
>> // bad_cast example
>> #include <iostream> // std::cout
>> #include <typeinfo> // std::bad_cast
>>
>> class Base {virtual void member(){}};
>> class Derived : Base {};
>>
>> int main () {
>> try
>> {
>> Base b;
>> Derived rd = dynamic_cast<Derived>(b);
>> }
>> catch (std::bad_cast& bc)
>> {
>> std::cerr << "bad_cast caught: " << bc.what() << '\n';
>> }
>> return 0;
>> }
>>
>> I should mention that it IS a bad_cast exception if I include
>> ampersands
> (&) in
>>
>> Derived& rd = dynamic_cast<Derived&>(b);
>>
>> but why?
>
> So in the example that compiles, with ampersands, (I include the
> example again below) why doesn't it simply return rd=nullptr, why does
> it throw an exception.

A reference cannot have nullptr value.

> My question I guess is, when does dynamic cast
> throw an exception and when does it return nullptr?

It returns nullptr if this is possible, otherwise throws.
0 new messages