Symbian and Qt both have extensive coding standards to ensure code safety and ease of maintainance. A convention also exists for filenames to show which files include public or private content.
Symbian's coding standards cover code formatting, safety, ease of maintenance and efficiency. This topic provides a summary of the most applicable points from the standard that relate specifically to Symbian idioms.
For a full introduction to the Symbian idioms and conventions, see Introduction to Symbian C++ development.
Code safety
Memory allocation failure
When memory is allocated on the heap,
it is essential to determine whether the allocation succeeded or failed,
and act accordingly. Use the leaving overload of the new
operator (new(ELeave)
), or check the pointer returned
from the call to allocate the memory against NULL
.
No side-effects from assertions
Assertion statements must not perform ‘side effects’, such as modifying the value of a variable.
Strings and buffers
Use proven
string classes like the Symbian descriptor
classes in preference to native strings and memory buffers
or hand-crafted string classes. Classes provided by the Qt application
framework (QString
and QByteArray
) are suitable alternatives and classes provided by the STL ports
available. Be extremely careful when dealing with C-style strings
and arrays.
Multiple inheritance
Only use multiple
inheritance through interfaces defined by M classes.
Inherit from one CBase
-derived class and one or
more M classes. (Put the CBase-derived class first in the inheritance
list to ensure that destruction by the cleanup stack occurs correctly.)
Object construction
The code inside a C++ constructor must not leave.
Implement non-trivial construction and initialization
code that can fail in the second phase of a two-phase constructor,
typically in a ConstructL()
method.
Safe cleanup
Use the cleanup stack to avoid orphaning memory or resources in the event of a leave.
If an object is deleted, do not put it on the cleanup stack.
An object must not be simultaneously owned by another object and on the cleanup stack. This means that class member data should never be placed on the cleanup stack if it is also destroyed in the class destructor, as is usually the case.
Functions with a ‘C’ suffix on their name (such as NewLC()
) automatically put a pointer to the object(s) they allocate on the
cleanup stack. Therefore, those objects must not also be pushed on
to the cleanup stack explicitly or they will be present twice.
A TRAP
can be used within a destructor of a class
stored on the heap. However, it is not safe to use a TRAP within any
destructor that may be called as the stack unwinds.
When calling
code that can throw a C++ exception, catch everything and convert
the exceptions to leaves. TRAP and TRAPD panic if they receive a C++
exception that was not raised by a Symbian leave (of type XLeaveException
).
Ease of maintenance
Use and comment assertions
Use the __ASSERT_DEBUG
assertion macro liberally to detect programming errors. It may sometimes
also be appropriate to use __ASSERT_ALWAYS
to catch
invalid runtime input.
Use comments to explain assertion statements and the assumptions they make. This makes the code easier to maintain.
Naming conventions
Use the concrete types defined
in e32def.h
in lieu of the language-defined basic
types. For example, use TInt
instead of int
.
Interface classes
Use M classes to specify the interface only, not the implementation. Generally M classes should contain only pure virtual functions.
Descriptor parameters
When using descriptors as function parameters, use the base
classes (TDes
and TDesC
) and pass
them by reference.
Handling date and time values
Use the Symbian date and time classes (such as TDateTime
and TTime
) instead of hand-crafted alternatives.
Static factory functions
Where two-phase construction
is used, provide one or more public static factory functions (typically
called NewL()
and NewLC()
) for object
construction. The construction methods themselves should be private
or protected.
Check correct cleanup
Use the checking
methods of CleanupStack::Pop()
and CleanupStack::PopAndDestroy()
where possible, to check that PushL()
and Pop()
calls are balanced.
Efficiency
Minimize stack use
Minimize stack use as much as is
possible. For example, use the heap to store large data structures
instead of the stack and take care when declaring larger stack-based
variables within loops or recursive functions. Use of the TFileName
and TParse classes is a common
cause of stack consumption, because objects of both these types are
over 512 bytes in size. (Remember that the default stack size is only
8KB.)
Avoid writable global data in DLLs
Where possible avoid the use of writable global data in DLLs.
Literals
Do not use the _L
macro for literal descriptors
except where it is convenient to do so in test code. Instead , use
the _LIT
macro for literal descriptors.
Qt provides a compact set of coding guidelines that are separated into Coding Style and Coding Conventions. The former defines best-practice for code format and layout, while the conventions discuss C++ features you should not use, approaches to including headers, casting, maintaining binary compatibility, and compiler specific issues. As you would expect, there is a clear focus on coding to ensure cross platform compatibility.
Qt applications should follow the Qt Coding Style rules for code layout in both Symbian C++ and Qt code. In other respects the Qt code should follow the Qt conventions and Symbian C++ code should follow the Symbian programming conventions.
This approach is followed in
the Telephony application accompanying this documentation. The exception
to this rule is that the TelephonyPrivate
class is
a Symbian C class (derived from CActive
), and should
therefore be named using the C
prefix. However,
this prefix is not used in order to maintain the "opacity" of the
private implementation. The risk of not using the class prefix is
low because the Telephony
class is its only user.
QMyClass
: The private class is QMyClassPrivate
.
Public class source and header files share the name of the
public class: qmyclass.h,qmyclass.cpp
.
Private class headers and source file names are terminated
with _p
(such as qmyclass_p.h
) unless the file is a platform-specific implementation.
Platform-specific implementation headers and source files include
the platform in the file name - e.g. qmyclass_symbian.cpp
(the _p is not necessary because it is implied).
Most of the material in this topic is based with permission on the Symbian Foundation wiki articles Apps:Using Qt and Symbian C++ Together and Coding Standards Quick Start. The versions used were those available at Symbian Foundation on 3 November 2010. The content in this page is licensed under the Creative Commons Attribution-Share Alike 2.0 UK: England & Wales License (http://creativecommons.org/licenses/by-sa/2.0/uk).