Coding standards and conventions

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 coding standards

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 coding standards

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.

Coding standards for mixed Symbian C++ and Qt code

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.

File and class naming conventions

In general, if the public class is called 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).

Copyright note

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).