# Why does catching C++ bad_cast not work?



## FooBarWidget (Jan 19, 2013)

I'm on FreeBSD 9.1. Consider the following code:

```
#include <exception>
#include <typeinfo>
#include <stdio.h>

class foo {
public:
    virtual ~foo() {}
};

class bar: public foo {
public:
    int val;
    bar(): val(123) {}
};

static void
cast_test(const foo &f) {
    try {
        const bar &b = dynamic_cast<const bar &>(f);
        printf("%d\n", b.val);
    } catch (const std::bad_cast &) {
        printf("bad cast\n");
    }
}

int main() {
    foo f;
    cast_test(f);
    return 0;
}
```

On FreeBSD:

```
$ g++ badcast.cpp -o badcast -Wall && ./badcast
terminate called after throwing an instance of 'std::bad_cast'
  what():  std::bad_cast
Abort trap (core dumped)

$ g++ badcast.cpp -o badcast -frtti -fexceptions -Wall && ./badcast
terminate called after throwing an instance of 'std::bad_cast'
  what():  std::bad_cast
Abort trap (core dumped)

$ gcc -v
Using built-in specs.
Target: amd64-undermydesk-freebsd
Configured with: FreeBSD/amd64 system compiler
Thread model: posix
gcc version 4.2.1 20070831 patched [FreeBSD]

$ uname -a
FreeBSD freebsd9 9.1-RELEASE FreeBSD 9.1-RELEASE #0 r243825: Tue Dec  4 09:23:10 UTC 2012     
root@farrell.cse.buffalo.edu:/usr/obj/usr/src/sys/GENERIC  amd64
```

On Debian Linux 6:

```
$ g++ badcast.cpp -o badcast -Wall && ./badcast
bad cast
```

On OS X 10.8:

```
$ g++ badcast.cpp -o badcast -Wall && ./badcast
bad cast
```

Why does catching bad_cast not work on FreeBSD?


----------



## nslay (Jan 20, 2013)

That's certainly strange. I originally thought it was a bug in GCC 4.2, but it affects clang and GCC 4.6 also.

Maybe you should file a ticket.


----------



## FooBarWidget (Jan 20, 2013)

I've reported the bug at http://www.freebsd.org/cgi/query-pr.cgi?pr=175453.


----------



## nslay (Jan 22, 2013)

I think the ticket should be classed _critical_ with priority _high_. It's a fundamental feature of the C++ language that should *never* have problems.


----------



## Uniballer (Jan 22, 2013)

nslay said:
			
		

> I think the ticket should be classed _critical_ with priority _high_.



It sounds like you're saying that you think everybody doing anything on FreeBSD should stop what they're doing and work on this problem that annoys you.  Good luck with that.


----------



## nslay (Jan 22, 2013)

Uniballer said:
			
		

> It sounds like you're saying that you think everybody doing anything on FreeBSD should stop what they're doing and work on this problem that annoys you.  Good luck with that.



No, that's not what I'm saying at all. I'm saying that there are thousands of ports written in C++ and several utilities in the source tree written in C++ that rely on standard language behavior (such as catching exceptions!).

It's not a just mere annoyance ... it's a serious problem that potentially affects any C++ application running on FreeBSD.


----------



## kpa (Jan 22, 2013)

No, this is a real problem that must be solved somehow. Catching exceptions must work, how else can you claim that the implementation is standards conforming?


----------



## Uniballer (Jan 23, 2013)

My guess is that unless somebody makes it their pet project it won't get done.  For example, the terminal driver is no longer POSIX compliant as of 8.0 due to issues with tcdrain(3).  This problem broke standards compliant working code.  Multiple SPRs have been written (including one by phk) pointing this out, but no action has been taken.  It appears that because essentially nothing in the base code depends on this feature nobody cares to work on the problem.


----------



## FooBarWidget (Jan 23, 2013)

Sigh, I'm amazed that people can say things like that.

This isn't a small thing that's broken. This is one of the *most fundamental* C++ language properties being broken. It's almost like "rm -f" not working anymore.

The Phusion Passenger web application server depends on this feature. Break dynamic_cast, and you break a majority of the Ruby web apps out there. I discovered this bug while testing Phusion Passenger on FreeBSD 9.1.


----------



## Uniballer (Jan 23, 2013)

This seems to have worked in the past.  It fails on i386 and amd64 under 9.1, but seems to work on i386 under 8.3.

Did it work on 9.0?


----------



## FooBarWidget (Jan 23, 2013)

People reported that it works on 9.0. I tested on x86_64 8.0, which worked too.


----------



## FooBarWidget (Jan 23, 2013)

The FreeBSD developers are already working on it.


----------

