Description of Problem: It is impossible to throw exceptions in the overflow() method of own std::streambuf subclasses. I think this happens because streambuf::overflow() is called by C functions and gcc can not pass exceptions through them. But the C++ standard says in 27.5.2.4.5 [lib.streambuf.virt.put]: | int_type overflow(int_type c = traits::eof()); | ... | Returns: traits::eof() or throws an exception if the function fails. so exceptions should be possible there How Reproducible: ---- example.cc ------------ #include <iostream> struct foo : public std::streambuf { int overflow(int c = EOF) { throw int(42); } }; int main() try { foo a; std::ostream b(&a); b << '1'; } catch (...) { std::cout << "Ok" << std::endl; } ------------------------ Steps to Reproduce: 1. compile and run program above Actual Results: $ ./a.out Aborted (core dumped) Expected Results: $ ./a.out Ok Additional Information: $gdb a.out core (gdb) bt #0 0x400c17f1 in __kill () from /lib/i686/libc.so.6 #1 0x400c15ca in raise (sig=6) at ../sysdeps/posix/raise.c:27 #2 0x400c2d72 in abort () at ../sysdeps/generic/abort.c:88 #3 0x40050efb in __default_terminate () at ../../gcc/libgcc2.c:3034 #4 0x40050f1a in __terminate () at ../../gcc/libgcc2.c:3034 #5 0x40051c55 in throw_helper (eh=0x4006ec80, pc=0x4010bf5b, my_udata=0xbffff4d0, offset_p=0xbffff4cc) at ../../gcc/libgcc2.c:3168 #6 0x40051e7a in __throw () at ../../gcc/libgcc2.c:3168 #7 0x08049217 in foo::overflow () at tmp/exc.cc:5 #8 0x40110720 in __overflow (f=0xbffff690, ch=49) at genops.c:200 #9 0x4010bf5c in _IO_putc (c=49, fp=0xbffff690) at putc.c:33 #10 0x40049738 in ostream::operator<< () from /usr/lib/libstdc++-libc6.2-2.so.3 #11 0x08048fda in main () at tmp/exc.cc:14 #12 0x400b0177 in __libc_start_main (main=0x8048f90 <main>, argc=1, ubp_av=0xbffff7ac, init=0x8048be4 <_init>, fini=0x8049250 <_fini>, rtld_fini=0x4000e184 <_dl_fini>, stack_end=0xbffff79c) at ../sysdeps/generic/libc-start.c:129 $ rpm -q glibc gcc gcc-2.96-84 glibc-2.2.2-10
gcc can pass exceptions through C functions if they were compiled with -fexceptions. A couple of routines in glibc are (such as sort, bsearch, etc.), most of them are not. In this particular case: #0 0x080491d8 in foo::overflow (this=0xbffff970, c=49) at o.C:5 #1 0x4010a200 in __overflow (f=0xbffff970, ch=49) at genops.c:200 #2 0x40105a4c in _IO_putc (c=49, fp=0xbffff970) at putc.c:33 #3 0x400446c8 in ostream::operator<< () from /usr/lib/libstdc++-libc6.2-2.so.3 genops.c was compiled with -fexceptions while putc.c was not. This test fails with egcs 1.1.2 and gcc-2.95.2, but works with libstdc++-v3, so IMHO it is not worth bloating glibc because of this when gcc 3.0 will be out soon. A fully standard compliant libstdc++ is not anything below libstdc++-v3 anyway, so this is just yet another incompatibility.