TRAPs and Leaves

in

If you are new to Symbian programming, you may have notice that it is quite common to have functions name with trailing L, LC or LD. These letters have an important meaning:
-  L indicates a function that may Leave. We will talk about this below.
-  C indicates a function that add something on the Cleanup Stack (we will talk about this in a future article).
-  D indicates a function that takes ownership of a heap allocated object (and that will be responsible for its Deletion).

A "Leave" causes execution of the active function to terminate, and on through all calling functions, until the first function is found that contains a TRAP() or TRAPD() macro [*]. This is pictured by the code below:

leave.png

A leaving function ("L function") is:
-  a function that calls explicitly User::Leave() or one of its derivates (LeaveIfNull(), LeaveIfError(),...
-  a function that calls new(ELeave). Note that is new(ELeave) is the short form for the last part of the code shown above.
-  a function that calls another L function without a trap harness.

If one of this condition is met, then it is a convention to add a L suffix to your function name.

This convention is really helpful when you implement virtual functions: if the virtual function is a Lfunction then your implementation can leave (ex: CCoeControl::OfferKeyEventL(), CCoeControl::HandleCommandL(),...). If not, your function shall not leave (ex: CCoeControl::Draw()). If you need to call an L function in your implementation, then you must use a trap harness to "catch the leave":

void MyControl::Draw(const TRect& aRect)
{
...
TRAPD(errorcode,MyLeavingFunctionL());
...
}

[*]  This definition is taken from Martin Tasker's Professional Symbian Programming: Mobile Solutions on the EPOC Platform.


like exceptions?

So this is very similar to try and exception handling is it not? similarities? differences?

> like exceptions?

It is very similar to Exceptions. The Symbian Leave and Trap pattern was established before C++ support for exceptions was finalised and correctly supported in gcc.

Trap and leave are used for rolling back operations. And the rules of writing exception safe code apply equally to leaves. So brush up on the lessons of C++ gurus such as Herb sutter.

leave do have limitations compared with exceptions.

1. You can only leave with a TInt error code. exceptions can throw any kind of object, which offers the possiblity to throw more context.

2. Destructors are not called leaves are implemented in a similar way to long jumps which means that destructors of stack based objects will not be called as a result of an exception. To get around this, the leave mechanism is complemented by the cleanup stack. On leave, anything that needs to be destroyed in order to achive successful rollback (and freeing of resources) should be pushed on the cleanup stack. The cleanup stack is a manager object and used in roughly the same way as TAutoPtr. See the link

3. Leave safety is not enforced by the compiler. Ony a naming convention is used to denote the exception API.

With the forthcoming support for EABI binary inferface and rich compilers, Symbian will need to move over to a more industry standard exception mechanism.

how to execute the statement, when leave happens

Hi below is snap of code

ptr->ExecutecodeL( xxx); if (ptr->Exe() == (xxx) _LIT("success"); else _LIT("Error");

when i execute function ptr->Exe() function will leave. so I want to execute statement "_LIT("success");" even if it leaves. How can i implement this.

how to execute the statement, when leave happens

You should use a trap harness to do this and rename your Exe() function to ExeL() to indicate it can leave (the latter won't change anything in how the code behaves but will give an indication to other users of your code).

TInt res=KErrUnknown;
TRAPD(leaveCause, res=ptr->ExeL());
if(res==(xxxx))
{
 // success
}
else
{
// error
// use res and leaveCause to get further information
}

> TRAPs and Leaves

why not try-catch?

> TRAPs and Leaves, here'

No try-catch was available when Symbian was originally developed. AFAIK. (I read this from a magazine months ago.)

And now that we have this nice TRAP thingy, and it is widely used, we don't even want to change to try-catch!

> TRAPs and Leaves

void MyControl::Draw(const TRect& aRect) throw() ... try MyLeavingFunctionL()); catch(...) ...

what is diff?

> TRAPs and Leaves

Try Catch is not used in Symbian because of one more very important Reason, * It produces a lot of RAM overhead and also adds on considerably to the size of the compiled code. Thus The compilers are directed specifiaclly to Flag an error if C++ exeception handling is used.