Can an object throw itself?

Answering a recent question about exceptions, reminded me of an old query.

The following compilation in C ++

#include <iostream> using namespace std; struct weird { void danger() { throw *this; } }; int main() { weird object; object.danger(); return 0; } 

However, it always leads to a runtime error.

  • Does the object throw while expanding the stack?

  • A runtime error smells like calling terminate , how is it caused?

  • If a weird object was declared in the scope (global here), can this work in the inner scope? (where unwinding this stack will not affect higher ones?)

+8
c ++ exception
source share
2 answers

The result is a call to std::terminate() , because the exception never throws. Change it to the following and it works fine:

 int main() { weird object; try { object.danger(); } catch (weird &w) { std::cout << "caught weird\n"; } } 
  • Is an object saved while unwinding the stack to be thrown?

When an exception is thrown, the mechanism for throwing exceptions makes a copy of the thrown value into some private memory somewhere, so the lifetime of the "thrown" object does not matter.

(Of course, if you throw out the pointer, then the value of the pointer is saved, not the object pointing to the object. In this case, you must make sure that capture handlers do not perform illegal actions with the value of the pointer, either by ensuring the object still exists or that the handler catch does not interfere with the pointer.)

  • A runtime error smells like calling terminate , how is it caused?

When an exception is thrown, and there are no corresponding C ++ statements that should call std::terminate() . The exception throwing mechanism responsible for finding a suitable capture handler implements this by calling std::terminate() when it fails to find the appropriate catch handler.

  • If the weird object was declared in the scope (global here), can this work in the inner scope?

Whether it is global or not does not matter; exception throwing behavior is (mostly) well defined anyway.

(One thing specified in the implementation is if the stack is unwound before std::terminate() is called when the catch handler is not found. I assume that in most implementations the stack is not unwound in this case.)

+12
source share

When it moves to exceptions in C ++, remember this: Throw away the value, understand the link .

"by value" = copy, copy = you no longer need to worry about what happens to the original object.


Side note. If you go to throw your own types, you better get them from std::exception .

0
source share

All Articles