10

Is it ok to just call throw; from constructor if something goes awry, and you have no idea how to recover?

The idea is to let the app crash with a dump, as the state is unknown. Or should you always specify an argument?

From MSDN I only found that it rethrows if there is no argument, but no idea what happens if there is no initial exception to rethrow.

Coder
  • 3,695
  • 7
  • 27
  • 42
  • If you want to get a crash, just `abort()` or `assert(false)`. That will provide a dump (depending on your system configuration) and is less confusing than an error message saying that the program terminated because of a `throw;` with no prior exception. – David Rodríguez - dribeas Feb 08 '11 at 11:13

6 Answers6

17

No. throw; is a special syntax that re-throws current exception. It only makes sense inside catch blocks (or code called from one) to continue propagating the exception.

Just use:

#include <stdexcept>
...
throw std::runtime_error("some description");

or even just

throw "some description";

but the later is uglier to handle and just generally frowned upon.

Jan Hudec
  • 73,652
  • 13
  • 125
  • 172
16

If there's no exception currently being processed throw; will lead to terminate() being called immediately and that will end your program abnormally. That is not very convenient - you'll have less information about what happened compared to throwing a meaningful exception. You could have thrown a meaningful exception, catch it at the top level (like main()), write some diagnostics and then end the program.

Community
  • 1
  • 1
sharptooth
  • 167,383
  • 100
  • 513
  • 979
  • 1
    There is a slight advantage in a program dump: you can inspect what the state of the whole program is, and try to analyze how the system got there. I tend throw an exception when you can recover, and die when you cannot, so that most state can be processed. – David Rodríguez - dribeas Feb 08 '11 at 11:23
  • Hmm, yes, the stack unrolling is unwanted in this case. But Terminate doesn't save stack info as well, does it? – Coder Feb 08 '11 at 12:02
2

An ASSERT might make your life easier to dignose what's going wrong

James
  • 9,064
  • 3
  • 31
  • 49
  • @Maxim: if you test suite is comprehensive, you don't need the test in release builds (I usually keep the test but throw instead...) – Matthieu M. Feb 08 '11 at 10:39
  • 1
    @Maxim If you disable asserts for the "release" build - usually you get what you deserve : a random program state, if very lucky a crash. Murphy's law. – BЈовић Feb 08 '11 at 10:50
  • 1
    @VJo: You are not using asserts correctly. Have you heard of checking error codes and exceptions? – Maxim Egorushkin Feb 08 '11 at 10:59
  • @Maxim I did. Asserts are to prevent impossible parameters being passed to a function. The problem with disabling asserts is it is most likely a micro-optimization. btw I assumed that the ASSERT macro (from the answer) is throwing an exception. – BЈовић Feb 08 '11 at 11:04
  • @VJo: make a google search for "c++ assert" and re-read the first hit then. – Maxim Egorushkin Feb 08 '11 at 11:06
  • @Maxim I am not sure how to respond to the last comment, as I am not sure if you are joking or not. The hit I got is from cplusplus.com and says that the asserts to capture programming errors, which can pass the testers. Reread my comment again – BЈовић Feb 08 '11 at 11:51
  • "Therefore, this macro is designed to capture programming errors, not user or running errors, since it is generally disabled after a program exits its debugging phase." – Maxim Egorushkin Feb 08 '11 at 11:55
  • I think ASSERT or was it VERIFY is nop'ed in release builds. So ASSERT(DooFoo()); will not be called at all. – Coder Feb 08 '11 at 12:00
2

While technically you can call it, it won't do what you'd like.

The simplest solution is to call throw std::runtime_exception("thrown from Foo");, which at the same time gives some feedback about what was going on.

Matthieu M.
  • 287,565
  • 48
  • 449
  • 722
2

When you say "no idea how to recover" what you mean I presume is that at this point you do not know how to handle the error?

Perhaps you are not getting the point of exceptions. You throw information: that the exception occurred and why. The call-stack is then unwound to the point where it can be handled. At that point in the code we know how, if possible, to recover.

CashCow
  • 30,981
  • 5
  • 61
  • 92
  • Yes, some impossible, unexpected condition happened, like undocumented error in third party library, out of memory error, bit flip, or something like that. – Coder Feb 08 '11 at 11:59
1

Technically, you can do that because throw without argument and without an active exception just calls terminate() which by default calls abort(). I prefer calling abort() directly, it requires less cognitive effort to recognize what is going on.

Maxim Egorushkin
  • 131,725
  • 17
  • 180
  • 271