Ответ 1
Это ошибка в GCC (Ошибка 80683).
Если конструктор является первым оператором op в предложении try/catch
, тогда компилятор считает его вне его, хотя он должен включать его.
Например, следующее работает просто отлично:
#include <iostream>
struct A {
A(int e) { throw e; }
};
struct B {
A a{42}; // Same with = 42; syntax
};
int main() {
try {
// The following forces the compiler to put B contructor inside the try/catch.
std::cout << "Welcome" << std::endl;
B b;
} catch (int e) {
std::cout << "ERROR: " << e << std::endl; // This is just for debugging
}
return 0;
}
Продолжительность:
g++ -std=c++11 test.cpp -DNDEBUG -o test; ./test ; echo $?
Выходы:
Welcome
ERROR: 42
0
Я предполагаю, что из-за оптимизации компилятора он переводит конструктор в начало основной функции. Он предполагает, что struct B
не имеет конструктора, тогда он предполагает, что он никогда не будет генерировать исключение, поэтому безопасно перемещать его за пределы предложения try/catch
.
Если мы сменим объявление struct B
на явно, используйте конструктор struct A
:
struct B {
B():a(42) {}
A a;
};
Тогда результат будет таким, как ожидалось, и мы введем try/catch
даже при удалении распечатки "Добро пожаловать":
ERROR: 42
0