I saw a very interesting snipped of code on the newsgroups the other day. It showed how people can so easily misuse Symbian programming idioms if they are not careful
RArray<TInt>* array = new (ELeave) RArray<TInt>; array->Append(1); array->Append(2); delete array;
This is not the original class, the original class used another R class but the problem is still the same. To all intents and purposes this look like safe c++ code but the coder failed to realize that an RClose MUST be closed and cannot be deleted.
I wonder how many other people have been bitten by this issue?
RClasses as an idiom work quite well for real resources or references to objects owned by other threads. But are pretty confusing when used as datastructures.
The general rule of R classes is that you should never "new" them since it should be possible to copy R classes by value. As an example and RString is a handle to a real string owned by an RStringPool object - so copying the RString would mean copying just the handle and not the whole string. However, there are many exceptions to this rule in Symbian OS.
Here is where it gets confusing:
If you have RArray<TInt> a; a.Append(12); RArray<TInt> b= a; a.Close() RDebug::Print("%D",b[1]); <---- Does this work?
Is b still a valid copy? I.e was the RArray contents reference counted.
In my view Symbian should have used R classes only for things which derive from RHandleBase and have a clear policy for duplication and sharing accross threads and processes. Other classes which use R prefix are usually just proxy/pimpl objects.
Another one to watch out for is: RPointerArray - You must call ResetAndDestroy() before the call to Close() if you want all the objects delete. Close() only deletes the memory allocated to the container.
Re: Use and abuse of Symbian idioms
jplauril
| 06/06/2007, 16:50
/me raises hand.
I fixed a bug like this from my code just five minutes ago :)
Re: Use and abuse of Symbian idioms
TwmD | 06/06/2007, 15:44
The general rule of R classes is that you should never "new" them since it should be possible to copy R classes by value. As an example and RString is a handle to a real string owned by an RStringPool object - so copying the RString would mean copying just the handle and not the whole string.
However, there are many exceptions to this rule in Symbian OS.
Here is where it gets confusing:
If you have RArray<TInt> a;
a.Append(12);
RArray<TInt> b= a;
a.Close()
RDebug::Print("%D",b[1]); <---- Does this work?
Is b still a valid copy? I.e was the RArray contents reference counted.
In my view Symbian should have used R classes only for things which derive from RHandleBase and have a clear policy for duplication and sharing accross threads and processes.
Other classes which use R prefix are usually just proxy/pimpl objects.
Another one to watch out for is:
RPointerArray - You must call ResetAndDestroy() before the call to Close() if you want all the objects delete. Close() only deletes the memory allocated to the container.