Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can an object throw itself?

Tags:

c++

exception

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

The following compiles in c++

#include <iostream>
using namespace std;

struct weird {
    void danger()
    {
        throw *this;
    }
};

int main() 
{
    weird object;
    object.danger();
    return 0;
}

Yet it always results in runtime error.

  • Isn't the object thrown, preserved during stack unwinding?

  • The runtime error smells like a call to terminate, how is this caused?

  • If weird object was declared in an enclosing scope (the global here) could this work in an inner scope? (where unwinding that stack wouldn't affect superior ones?)

like image 823
Nikos Athanasiou Avatar asked Mar 07 '14 21:03

Nikos Athanasiou


People also ask

Why do objects thrown up eventually fall back to the earth?

A ball thrown upwards falls back towards the surface of Earth due to force of gravity. The force of gravity is a force.

When we throw something up in the air it comes down why?

Gravitational force of the earth acts on every object having mass. When an object is thrown upwards the gravitational force of the earth acts against the velocity of the object and pulls the object downwards, i.e, towards itself. thus the object returns back towards the earth.


1 Answers

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

int main() {
    weird object;
    try {
      object.danger();
    }
    catch (weird &w) {
      std::cout << "caught weird\n";   
    }
}
  • Isn't the object thrown, preserved during stack unwinding?

When an exception is thrown, the exception throwing mechanism 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 a pointer then the pointer value is preserved, not the pointed-to object. In that case you must ensure that catch handlers do not do illegal things with the pointer value, either by ensuring the object still exists, or that the catch handler does not deference the pointer.)

  • The runtime error smells like a call to terminate, how is this caused?

When an exception is thrown and there is no corresponding catch handler C++ states that std::terminate() must be called. The exception throwing mechanism responsible for finding an appropriate catch handler implements this by calling std::terminate() when it fails to find an appropriate catch handler.

  • If weird object was declared in an enclosing scope (the global here) could this work in an inner scope?

Whether it's global or not doesn't matter; the behavior of throwing the exception is (mostly) well defined either way.

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

like image 121
bames53 Avatar answered Sep 22 '22 06:09

bames53