Tuesday, June 16, 2009

Releasing Resources Is Destruction

Nearly everybody knows the popular design pattern RAII (Resource Aquisition Is Initialization).
In short: when getting a resource it has to be bound to a certain object (in C++ known as Smartpointers e.g. std::auto_ptr<>).

The clue is that releasing the resource is handled automatically through destruction of the management object. So this popular design pattern could also be called Releasing Resources Is Destruction (RRID).

When writing standard C++ applications it is ensured that stack located objects are destroyed via stack unwind in case the function returns normally (not by an exception). In Symbian OS C++ this is the case too. But what happens in case of an irregular return from a function (in case of an exception)?

In Standard C++ the compiler generates an unwind list for every function that creates objects on the stack. This unwind list is processed in case of an exception. So the created objects are destroyed. In Symbian OS before v9.1 such an unwind list simply did not exist. So POD types were simply deallocated (no destructor was called). But NonPOD types have to be pushed onto Symbian OS' so called CleanupStack. This stack is processed in case of an exception (and only in case of an exception). I never knew why the compiler implementers didn't implement CleanupStack unwind in case of regular returning from a function. But that's not the topic here.

The change since Symbian OS v9.1 is that the compiler generates an unwind list for functions which create objects on the stack and during stack unwind in case of an exception these objects are destroyed correctly (with a call to the destructor). This is why the auto_ptr<> class template is working nicely for Symbian OS v9.1 and later without the TCleanupItem object (see chapter 1.4 in the mentioned PDF).