$ cat gccexceptionbug.cxx #include <iostream> using namespace std; typedef int IntArray[10]; void test_array() throw (IntArray) { //void test_array() { static IntArray arr; for (int i=0; i<10; i++) { arr[i] = i; } throw arr; } int main () { cout << "Start" << endl; try { test_array(); } catch (IntArray) { cout << "Caught!" << endl; } cout << "Finish" << endl; return 0; } $ g++-3.4.0 -v -save-temps gccexceptionbug.cxx -o gccexceptionbug Reading specs from /usr/lib/gcc/i586-mandrake-linux-gnu/3.4.0/specs Configured with: ../configure --prefix=/usr --libdir=/usr/lib --with-slibdir=/lib --mandir=/usr/share/man --infodir=/usr/share/info --enable-shared --enable-threads=posix --disable-checking --enable-long-long --enable-__cxa_atexit --enable-clocale=gnu --disable-libunwind-exceptions --enable-languages=c,c++,java --program-suffix=-3.4.0 --host=i586-mandrake-linux-gnu --with-system-zlib Thread model: posix gcc version 3.4.0 (Mandrake Linux 10.0 3.4.0-1mdk) /usr/lib/gcc/i586-mandrake-linux-gnu/3.4.0/cc1plus -E -quiet -v -D_GNU_SOURCE gccexceptionbug.cxx -mtune=pentium -o gccexceptionbug.ii ignoring nonexistent directory "/usr/lib/gcc/i586-mandrake-linux-gnu/3.4.0/../../../../i586-mandrake-linux-gnu/include" #include "..." search starts here: #include <...> search starts here: /usr/lib/gcc/i586-mandrake-linux-gnu/3.4.0/../../../../include/c++/3.4.0 /usr/lib/gcc/i586-mandrake-linux-gnu/3.4.0/../../../../include/c++/3.4.0/i586-mandrake-linux-gnu /usr/lib/gcc/i586-mandrake-linux-gnu/3.4.0/../../../../include/c++/3.4.0/backward /usr/local/include /usr/lib/gcc/i586-mandrake-linux-gnu/3.4.0/include /usr/include End of search list. /usr/lib/gcc/i586-mandrake-linux-gnu/3.4.0/cc1plus -fpreprocessed gccexceptionbug.ii -quiet -dumpbase gccexceptionbug.cxx -mtune=pentium -auxbase gccexceptionbug -version -o gccexceptionbug.s GNU C++ version 3.4.0 (Mandrake Linux 10.0 3.4.0-1mdk) (i586-mandrake-linux-gnu) compiled by GNU C version 3.4.0 (Mandrake Linux 10.0 3.4.0-1mdk). GGC heuristics: --param ggc-min-expand=47 --param ggc-min-heapsize=32000 as -V -Qy -o gccexceptionbug.o gccexceptionbug.s GNU assembler version 2.14.90.0.5 (i586-mandrake-linux-gnu) using BFD version 2.14.90.0.5 20030722 /usr/lib/gcc/i586-mandrake-linux-gnu/3.4.0/collect2 --eh-frame-hdr -m elf_i386 -dynamic-linker /lib/ld-linux.so.2 -o gccexceptionbug /usr/lib/gcc/i586-mandrake-linux-gnu/3.4.0/../../../crt1.o /usr/lib/gcc/i586-mandrake-linux-gnu/3.4.0/../../../crti.o /usr/lib/gcc/i586-mandrake-linux-gnu/3.4.0/crtbegin.o -L/usr/lib/gcc/i586-mandrake-linux-gnu/3.4.0 -L/usr/lib/gcc/i586-mandrake-linux-gnu/3.4.0 -L/usr/lib/gcc/i586-mandrake-linux-gnu/3.4.0/../../.. gccexceptionbug.o -lstdc++ -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc /usr/lib/gcc/i586-mandrake-linux-gnu/3.4.0/crtend.o /usr/lib/gcc/i586-mandrake-linux-gnu/3.4.0/../../../crtn.o $ $ ./gccexceptionbug Start terminate called after throwing an instance of 'int*' Aborted $ Note that if the exception specification in the definition of test_array() is removed, the exception is caught. (Replace with the commented out line). The same behaviour was observed in gcc version 3.3.1 (cygming special).
If I recall correctly from my reading of the standard arrays get decayed to pointers for things like this (and a couple of others too).
Confirmed. Here's a small testcase: ------------------- typedef int IntArray[10]; IntArray i; void test_array() #ifdef TEST throw (IntArray) #endif { throw i; } int main () { try { test_array(); } catch (IntArray) {} } ------------------ We get g/x> /home/bangerth/bin/gcc-3.4-pre/bin/c++ x.cc ; ./a.out g/x> /home/bangerth/bin/gcc-3.4-pre/bin/c++ x.cc -DTEST ; ./a.out terminate called after throwing an instance of 'int*' Aborted The point is that if we throw an exception that violates the exception specification, then it is converted into an unspec exception and we abort. However, since we can catch the exception that we throw in the main function if there is no exception specification on the function body, it seems as if the exception thrown is really of type IntArray and shouldn't violate the exception specification. I agree that this is confusing and looks like a bug in gcc associated with decaying arrays to pointers, though I'd like to solicit a second opinion on this. We get the same results for all gcc versions from 2.95 to mainline. W.
Confirmed.
Subject: Bug 15745 Author: jason Date: Thu Sep 6 03:33:46 2007 New Revision: 128174 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=128174 Log: PR c++/15745 * except.c (prepare_eh_type): Use type_decays_to. Added: trunk/gcc/testsuite/g++.dg/eh/spec9.C Modified: trunk/gcc/cp/ChangeLog trunk/gcc/cp/except.c trunk/gcc/testsuite/g++.dg/ext/vla4.C
Subject: Bug 15745 Author: jason Date: Mon Oct 1 20:53:09 2007 New Revision: 128917 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=128917 Log: PR c++/15745 * except.c (prepare_eh_type): Use type_decays_to. Modified: branches/gcc-4_2-branch/gcc/testsuite/g++.dg/ext/vla4.C
Fixed.