Provides code snippets to show you how to use 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 }
Notes
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 { // didn’t leave: value valid }