Почему это вызывает завершение, если я пытаюсь бросить что-то внутри блока catch в C++
У меня есть следующий код C++, и это удивляет меня. Проблема заключается в том, что если я что-то выбрасываю, кроме re-throw внутри блока catch, программа будет прервана вызовом abort и выдаст сообщение об ошибке в GCC4, "terminate вызывают после выброса экземпляра int". Если я просто использую "бросить"; перебросить внутрь блока catch, все будет хорошо.
#include <iostream>
#include <exception>
#include <stdexcept>
using namespace std;
int main()
{
try{
throw std::string("first throw");
}
catch(std::string &x){
try{
std::cout << x << std::endl;
// throw; // if I use this line, all is fine.
throw int(2); // but if I use this line, it causes Abort() to be called
}
catch (int &k){
throw;
}
catch(...)
{
cout << "all handled here!"<< endl;
}
}
catch(...){
std::cout<< "never printed" << endl;
}
}
2 ответа
Если вы бросаете int
тогда это не будет обработано; это будет поймано внутренним catch (int &k)
обработчик, который его отбрасывает; и нет никакого внешнего обработчика, чтобы поймать переброшенное исключение, так как вы уже находитесь во внешнем catch
блок. Так что в этом случае terminate
вызывается из-за необработанного исключения.
Если вы сбросите string
тогда это ловится внутренним catch(...)
обработчик; это не сбрасывает, поэтому исключение было обработано.
Вы throw
не внутри какой-либо try
обработчик, таким образом, это приводит к abort
будучи призванным
Вот ваш код с очищенным отступом и некоторыми комментариями:
#include <iostream>
#include <exception>
#include <stdexcept>
using namespace std;
int main()
{
try {
throw std::string("first throw");
}
catch (std::string &x) {
try {
std::cout << x << std::endl;
// throw; // if I use this line, all is fine.
throw int(2); // but if I use this line, it causes Abort() to be called
}
catch (int &k) {
// Catches and rethrows exception. Not inside a try thus leads to abort.
throw;
}
catch (...) {
// Will handle the case where the string is rethrown instead. No abort.
cout << "all handled here!"<< endl;
}
}
catch (...) {
std::cout<< "never printed" << endl;
}
}