try {Optionally a function may declare that it throws exceptions:
throw <somevalue>;
}
catch ( <sometype> [<var>] ) {
/* ... */
}
catch ( ... ) {
/* any exception */
}
void func() throw(...) { /* ... */ }
Note that catch variable is assigned by copy.
Catching an exception in a constructor assignment requires special
syntax:
C::C(int ii)
try // function-try block
: i(f(ii))
{ /* body of function goes in try block */ }
catch (...) {
/* any exception incl. constructor initializer */
}
Destructors of stack variables in the completed try scope are called
when an exception is thrown.
TRAP(_r,_s) {TTrap __t;if (__t.Trap(_r)==0){_s;TTrap::UnTrap();}}
TRAPD(_r,_s) TInt _r;{TTrap __t;if (__t.Trap(_r)==0){_s;TTrap::UnTrap();}}
_r is the TInt-typed
variable which will receive the Leave reason value, _s is the C++ statement to be
executed as the try body.
Exception handling is performed by subsequent testing of the _r variable.
I don't think that destructors of stack variables are called, but
the current thread cleanup stack is unwound to the point at which the
TRAP harness was entered.
The cleanup stack is access via the CleanupStack class, and has
operations:
static void PushL(TAny* aPtr); // freed by User::free
TCleanupOperation,
static void PushL(CBase* aPtr); // freed by delete - has virtual destructor
static void PushL(TCleanupItem anItem); // freed by calling
//typedef void (*TCleanupOperation)(TAny*);
static void Pop();
static void Pop(TInt aCount); // aCount itemsstatic void Pop(TAny* aExpectedItem); // panic if top doesn't match in debug build
static void Pop(TInt aCount, TAny* aLastExpectedItem);
// panic if aCount-1 item doesn't match in debug build
static void PopAndDestroy();
static void PopAndDestroy(TInt aCount);static void PopAndDestroy(TAny* aExpectedItem);
static void PopAndDestroy(TInt aCount, TAny* aLastExpectedItem);
static void Check(TAny* aExpectedItem); // else panic
Symbian also has thread panics which are comparable to a number of
Java VM exceptions, but I don't think these are trappable in any way.
int _r;to implement TRAPD, where 'User::Leave(val)' maps to 'throw val'.
try {
_s;
} catch (int ex) {
_r = ex;
}
Java uses the Exceptions attribute of the class file method_info
structure to describe which exceptions are declared to be thrown by a
method.
Java uses the exception_table of the Code attribute to describe the
try/catch organisation of the code, specifying a table of start_pc
(inclusive) to end_pc (exclusive) of the try scope, handler_pc of the
catch code, and the catch_type, where 0 is any exception, else index of
exception CONSTANT_Class_info in the constant pool.
Strictly there is nothing to stop exception scopes being
overlapping, etc. But presumably most simple compilers will directly
reflect the nested structure of the source program.