Considering this silly looking try-catch
chain:
try {
try {
try {
try {
throw "Huh";
} catch(...) {
std::cout << "what1\n";
}
} catch(...) {
std::cout << "what2\n";
}
} catch(...) {
std::cout << "what3\n";
}
} catch(...) {
std::cout << "what4\n";
}
its output will surely be (and is) what1
, because it will be caught by the closest matching catch
. So far so good.
However, when I try to create a constructor for a class that tries to initialise a member via member initialiser list (which will result in an exception being raised) like so:
int might_throw(int arg) {
if (arg < 0) throw std::logic_error("que");
return arg;
}
struct foo {
int member_;
explicit foo(int arg) try : member_(might_throw(arg)) {
} catch (const std::exception& ex) { std::cout << "caught1\n"; }
};
int main() {
try {
auto f = foo(-5);
} catch (...) { std::cout << "caught2\n"; }
}
The output of the program is now:
caught1
caught2
Why is the exception being rethrown here (I assume that it is, otherwise why would two catch
es fire?)? Is this mandated by the standard or is it a compiler bug? I am using GCC 10.2.0 (Rev9, Built by MSYS2 project).