TRAP
Functions that leave, including functions that call other functions that can leave, must be executed under a trap harness.
If a call to User::Leave()
occurs within the function,
control will immediately be returned to the most recent TRAP
. A
variable is used with every trap to receive the error code specified in a
leave.
If no leave occurs, when the called function ends, execution
returns to the TRAP
, and the leave variable is unchanged.
Typically after a TRAP
, a function checks the leave
variable to test whether processing returned normally or by a leave, and acts
appropriately. Special mechanism discussed later are provided to handle cleanup
after the exception.
TInt E32Main()
{
testConsole.Title(); // write out title
testConsole.Start(_LIT("Example")); // start a new "test"
// The leave variable
TInt r=0;
// Perform example function. If it leaves,
// the leave code is put in r
TRAP(r,doExampleL());
// Test the leave variable
if (r)
testConsole.Printf(_LIT("Failed: leave code=%d"), r);
testConsole.End(); // finish
testConsole.Close(); // close it
return KErrNone; // and return
}
It is not necessary that all L functions be directly invoked by a trap harness. In most cases, functions that can leave are called normally by other functions. It is only necessary that somewhere above the function in the call chain is a trap harness.
For convenience, there is a TRAPD
form of the macro
which defines the variable to be used as the leave code. This saves a line of
source code in the majority of situations.
TRAPD(leaveCode,SomeFunctionL()); // call a function
if (leaveCode!=KErrNone) // check for error leave code
{
// some cleanup
}
Trap harnesses can be used when the function being called returns a result.
TRAPD(leaveCode,value=GetSomethingL()); // get a value
if (leaveCode!=KErrNone) // check for error leave code
{
// some cleanup
}
else { // didn’t leave: value valid
}