Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ exceptions catch clause [duplicate]

Tags:

c++

Possible Duplicate:
Scope of exception object in C++

I have the following catch clauses:

catch(Widget w);
catch(Widget& w);

void passAndThrowWidget() {
          Widget localWidget;
      throw localWidget;
}

If we catch Widget object by value, compiler will make copy so when we throw exception, localWidget goes out of scope, and we don't see any issues.

If we catch widget object byreference, according to reference concept, "w" points to same local Widget instead of copy. But i have seen most of the exceptions are caught by references in C++. My question how this works as "localWidget" goes out of scope when exception is thrown and catch by referense points to object which is destroyed.

Thanks!

like image 212
venkysmarty Avatar asked Jul 06 '11 04:07

venkysmarty


People also ask

Can an exception be caught twice?

Java does not allow us to catch the exception twice, so we got compile-rime error at //1 .

Is there a way to catch multiple exceptions at once and without code duplication in C#?

In C#, You can use more than one catch block with the try block. Generally, multiple catch block is used to handle different types of exceptions means each catch block is used to handle different type of exception.

What will happen if several catch statements match the type of an exception?

If multiple catch blocks match a particular exception type, only the first matching catch block executes when an exception of that type occurs. It's a compilation error to catch the exact same type in two different catch blocks associated with a particular try block.

Can you catch exceptions in C?

C itself doesn't support exceptions but you can simulate them to a degree with setjmp and longjmp calls.


3 Answers

throw expr; is similar to return expr; in that it uses copy initialization (list initialization is also possible with C++0x). But that's (mostly) syntax.

When it comes to semantics, then just as returning a value from a function returning a non-reference type is fine, so is throwing:

T f()
{
    // t is local but this is clearly fine
    T t;
    return t;

    // and so is this
    throw t;
}

Additionally it is unspecified whether what is returned or thrown is the result of the expression of the return or throw statement, or a copy (or move) from that expression.

The usual motivation for catching by reference has nothing to do with lifetime -- the lifetime of the thrown object is guaranteed to last at least as long as the catch clause. It is preferred because it allows exceptions to be designed and used polymorphically.

like image 142
Luc Danton Avatar answered Oct 22 '22 23:10

Luc Danton


The C++ runtime uses a memory location independent of the stack to store exception objects:

2.4.2 Allocating the Exception Object

Storage is needed for exceptions being thrown. This storage must persist while stack is being unwound, since it will be used by the handler, and must be thread-safe. Exception object storage will therefore normally be allocated in the heap, although implementations may provide an emergency buffer to support throwing bad_alloc exceptions under low memory conditions (see Section 3.3.1).

(from the C++ ABI for Itanium: Exception Handling)

So the reference you get when you "catch by reference" is a reference to that memory location, instead of a reference to a deallocated stack frame. This means exception objects are guaranteed to live long enough to be used by your exception handlers, even when obtained by reference. (They will probably be deallocated once you get out of the catch scope, though, so don't hold on to exception references.)

like image 3
zneak Avatar answered Oct 22 '22 22:10

zneak


Exceptions are the, well, exception to the rule of local scope:

try
{
    Widget w;
    throw w;
}
catch (const Widget& exc)
{
    // exc is a valid reference to the Widget
}

Even though local scope has ended, exceptions are handled in a special way, so what's thrown is still accessible.

like image 2
Tim Avatar answered Oct 22 '22 23:10

Tim