4

I am not able to understand, how following code is right,

class cls
{
    //just to create obj
};

int main(int argc, char* argv[])
{
    try
    {
        throw cls();//throwing obj as ref
    }
    catch(cls &ref)
    {
    }

    return 0;
}

I am throwing cls object as reference, will it not die as it comes out of { } scope?

Because catch block cannot access variables of try.

Pranit Kothari
  • 9,721
  • 10
  • 61
  • 137
  • 1
    Perhaps relevant: http://stackoverflow.com/questions/1654150/scope-of-exception-object-in-c – Stuart Golodetz Aug 05 '14 at 16:27
  • The relevant bit from the accepted answer there is "The exception object's scope is outside of the scope of the block where the throw occurs. Think of it as living in a special exception area off to one side of the normal call stack where local objects live." – Stuart Golodetz Aug 05 '14 at 16:28
  • The instance will go out of scope after it was handled in any appropriate `catch()` block. – πάντα ῥεῖ Aug 05 '14 at 16:28
  • 1
    You are not throwing a reference, you're throwing an object. You're just getting a reference to it in your handler. – sfjac Aug 05 '14 at 16:30

3 Answers3

1

When you throw an exception, you actually generate a copy of the exception object. It is the copy that is received by the catch block, so it is not out of scope even though the original object is.

Mark Ransom
  • 299,747
  • 42
  • 398
  • 622
  • That copy can be ellided though, even if ctor/dtor have side-effects. – Deduplicator Aug 05 '14 at 16:41
  • 1
    @Deduplicator if the copy is elided, it means the temporary object was never constructed, so the scope of the temporary becomes irrelevant. The end result is the same, an object outside the scope of the `throw` is passed to the `catch` block. – Mark Ransom Aug 05 '14 at 16:48
1

throw will copy initialize the object, which is how it is able to catch a reference. That said throwing arbitrary potentially non-complex objects around probably isn't as good as using std::exception

AJG85
  • 15,849
  • 13
  • 42
  • 50
0

The exception handling mechanism will take the value of the throw expression and copy it into a region of memory it has reserved for the purpose. Thus throwing an exception is always 'by value' and cannot be 'by reference.'

When an exception handler is activated then the catch parameter is initialized with the copy created by the exception handling mechanism: If the parameter is a reference type then it is initialized to reference that copy, if the parameter is not a reference type then it is initialized by copy construction.

bames53
  • 86,085
  • 15
  • 179
  • 244