![Symbian Developer Library](../../../../../../../a_stock/images/mainheading.gif)
![]() |
![]() |
|
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, then when the called function ends, execution
returns to the TRAP
, and the leave variable has the value
KErrNone
.
Typically after a TRAP
, a function checks the leave
variable to test whether processing returned normally or by leaving, and acts
appropriately. Special mechanisms 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;
// 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.
It is not recommended to call a function with an LC
suffix from inside a trap harness. This is because if the function does not
leave, the object that the function created and pushed onto the cleanup stack
will remain on the cleanup stack on exiting from the trap harness. This causes
a E32USER-CBase 71
panic, unless the object is popped by the
caller from within the trap harness, for example:
TRAPD(error, pointer = SomeClass::SomeFunctionLC(); CleanupStack::Pop(pointer));
In this code, if SomeClass::SomeFunctionLC()
leaves,
then pointer
is destroyed as part of leave processing. If it does
not leave then CleanupStack::Pop(pointer)
is called, avoiding the
panic.
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 { // didnt leave: value valid
}