Error with catching std::runtime_error as std::exception
15,281
The problem is with this line. Because throw
with an expression uses the static type of that expression to determine the exception thrown, this slices the exception object constructing a new std::exception
object copying only the base object part of the std::runtime_error
that e
is a reference to.
throw e;
To re-throw the caught exception you should always use throw without an expression.
throw;
Author by
BlueTrin
Working in an investment bank, writing analytics for Fixed Income products in a combination of C++, C# and Python.
Updated on July 23, 2022Comments
-
BlueTrin almost 2 years
we have a funny problem with try catch and std::runtime_error. Can someone explain to me why this is returning "Unknown error" as output ? Thanks very much for helping me !
#include "stdafx.h" #include <iostream> #include <stdexcept> int magicCode() { throw std::runtime_error("FunnyError"); } int funnyCatch() { try{ magicCode(); } catch (std::exception& e) { throw e; } } int _tmain(int argc, _TCHAR* argv[]) { try { funnyCatch(); } catch (std::exception& e) { std::cout << e.what(); } return 0; }
-
Björn Pollex over 13 years18 seconds faster ... how does he do it ?!
-
Doug over 13 yearsAh,
exception
's copy constructor doesn't have to preservewhat()
. I didn't realise that. -
BlueTrin over 13 yearsCharles, I thought that throw e; would call the copy constructor std::exception(const std::exception e), which would create a correct copy of the exception ? Is it not the case ?
-
CB Bailey over 13 yearsYes, it uses
std::exception
's copy constructor. No, this won't necessarily result in a 'correct' copy of the exception asstd::exception
is only the base class of the exception thate
actually refers to. -
BlueTrin over 13 yearsThank you for the complete answer, I have been taught to always rethrow using throw, while investigating an issue, I was curious about why the message returned by what() was not preserved. Thanks to you I know the reason, Charles !
-
Doug over 13 yearsUp until the draft from March this year, the standard says that the effect of calling
what()
on a copied exception is implementation-defined. As of March (N3090), theexception
copy constructor must ensure thatstrcmp(this->what(), rhs.what()) == 0
after copying anrhs
with dynamic type ofexception
. So it's guaranteed to print "FunnyError" in C++0x as written. -
Cubbi over 13 yearsException object slicing is also covered in More Effective C++, item 13.
-
BlueTrin over 9 yearsI didn't catch by value copy.