58
   S    Y    M    B    I    A    N     O    S  Symbian OS: Coding Conventions in C++ Version 1.0 May 5, 2004

Symbian OS Coding Conventions v1 0 En

Embed Size (px)

Citation preview

Page 1: Symbian OS Coding Conventions v1 0 En

8/4/2019 Symbian OS Coding Conventions v1 0 En

http://slidepdf.com/reader/full/symbian-os-coding-conventions-v1-0-en 1/58

   S

   Y

   M

   B

   I

   A

   N

 

   O

   S

 

Symbian OS: Coding

Conventions in C++Version 1.0May 5, 2004

Page 2: Symbian OS Coding Conventions v1 0 En

8/4/2019 Symbian OS Coding Conventions v1 0 En

http://slidepdf.com/reader/full/symbian-os-coding-conventions-v1-0-en 2/58

Symbian OS: Coding Conventions in C++ | 2

Legal Notice

Copyright © 2004 Nokia Corporation. All rights reserved.

Nokia and Nokia Connecting People are registered trademarks of Nokia Corporation.Java and all Java-based marks are trademarks or registered trademarks of SunMicrosystems, Inc. Other product and company names mentioned herein may betrademarks or trade names of their respective owners.

Disclaimer 

The information in this document is provided “as is,” with no warranties whatsoever,including any warranty of merchantability, fitness for any particular purpose, or anywarranty otherwise arising out of any proposal, specification, or sample. Furthermore,information provided in this document is preliminary, and may be changed substantiallyprior to final release. This document is provided for informational purposes only.

Nokia Corporation disclaims all liability, including liability for infringement of anyproprietary rights, relating to implementation of information presented in this document.Nokia Corporation does not warrant or represent that such use will not infringe suchrights.

Nokia Corporation retains the right to make changes to this specification at any time,without notice.

License

A license is hereby granted to download and print a copy of this specification for personal use only. No other license to any other intellectual property rights is grantedherein.

Version 1.0 | May 5, 2004

Page 3: Symbian OS Coding Conventions v1 0 En

8/4/2019 Symbian OS Coding Conventions v1 0 En

http://slidepdf.com/reader/full/symbian-os-coding-conventions-v1-0-en 3/58

Symbian OS: Coding Conventions in C++ | 3

Contents

1.  Introduction ......................................................................................................... 7 1.1

 Purpose and Scope.........................................................................................................7

 1.2  Motivation........................................................................................................................7 1.3  Document Outline ...........................................................................................................7 

2.  Coding Conventions ........................................................................................... 8 2.1  General Principles...........................................................................................................8 

2.1.1  Reusability..............................................................................................................8 2.1.2  Maintainability.........................................................................................................8 2.1.3  Build process ..........................................................................................................8 2.1.4  Internationalization .................................................................................................8 2.1.5  Specific Symbian OS issues...................................................................................9 

2.2  Source Files ....................................................................................................................9 2.2.1  General issues........................................................................................................9 2.2.2  File types ..............................................................................................................10 

2.3  Language ......................................................................................................................13 2.3.1  Naming and writing conventions ..........................................................................13 

2.4  Indenting Conventions ..................................................................................................21 2.4.1  Spacing.................................................................................................................21 2.4.2  Placement of braces and parentheses.................................................................21 

2.5  Commenting Conventions.............................................................................................22 2.5.1  General commenting conventions........................................................................22 2.5.2  Comment layouts..................................................................................................22 

2.6  Data Types and Usage .................................................................................................23 2.6.1  Constants..............................................................................................................23 2.6.2  Variables...............................................................................................................24 2.6.3  Types....................................................................................................................25 2.6.4  Typecasting ..........................................................................................................25 2.6.5  Pointers.................................................................................................................26 

2.7  Objects and Classes .....................................................................................................26 2.7.1  Class behavior......................................................................................................26 2.7.2  Class interfaces ....................................................................................................28 2.7.3  Virtual member functions......................................................................................29 2.7.4  Inline member functions .......................................................................................29 2.7.5  Multi-inheritance ...................................................................................................30 2.7.6  Cleanup stack.......................................................................................................30 

2.8  Internationalization Coding Guidelines .........................................................................30 2.8.1  Descriptors and character sets.............................................................................31 

Version 1.0 | May 5, 2004

Page 4: Symbian OS Coding Conventions v1 0 En

8/4/2019 Symbian OS Coding Conventions v1 0 En

http://slidepdf.com/reader/full/symbian-os-coding-conventions-v1-0-en 4/58

Symbian OS: Coding Conventions in C++ | 4

2.8.2  Text.......................................................................................................................31 2.8.3  Graphics and screen layout..................................................................................32 2.8.4  Locale-specific data..............................................................................................32 2.8.5

 Fonts.....................................................................................................................34

 3.  Coding Idioms ................................................................................................... 36 

3.1  General Principle...........................................................................................................36 3.1.1  Basic types ...........................................................................................................36 3.1.2  String and buffer classes......................................................................................36 3.1.3  Date classes .........................................................................................................36 3.1.4  Class types ...........................................................................................................37 3.1.5  Protect objects......................................................................................................37 

3.2  Exception Handling in Symbian OS C++ ......................................................................38 3.2.1  Check for out-of-resource errors ..........................................................................38 3.2.2  Conventional error-checking methods..................................................................39 3.2.3  Problems with conventional methods...................................................................39 

3.3  Solutions in Symbian OS ..............................................................................................40 3.3.1  Rule 1: Functions that leave, and trap harnesses................................................40 3.3.2  Rule 2: Using the cleanup stack...........................................................................42 3.3.3  Rule 3: Two-phase construction...........................................................................44 

3.4  Common Mistakes ........................................................................................................46 3.4.1  Misuse of TRAP and TRAPD ...............................................................................46 3.4.2  Misuse of the new operator ..................................................................................47 3.4.3  Misuse of the L suffix............................................................................................47 3.4.4  Memory leaks .......................................................................................................47 3.4.5  Using tools in the WINS/WINSCW emulator........................................................48 

3.5  Asserts and Panics .......................................................................................................50 4.  System Resource Usage (ROM and RAM) ...................................................... 51 

4.1  Importance ....................................................................................................................51 4.2  Reducing Code Size .....................................................................................................51 

4.2.1  Unnecessary exported functions..........................................................................51 4.2.2  Copy and paste ....................................................................................................51 4.2.3  Obviously decomposable functions......................................................................51 4.2.4  Excessive TRAP harnesses.................................................................................51 4.2.5  Debug code in release..........................................................................................52 4.2.6  Unnecessary virtual functions ..............................................................................52 4.2.7  Use common controls...........................................................................................52 4.2.8  Misuse of the _L macro ........................................................................................52 

4.3  Reducing RAM Usage...................................................................................................52 4.3.1  Use bit fields rather than many Tbools.................................................................52 

Version 1.0 | May 5, 2004

Page 5: Symbian OS Coding Conventions v1 0 En

8/4/2019 Symbian OS Coding Conventions v1 0 En

http://slidepdf.com/reader/full/symbian-os-coding-conventions-v1-0-en 5/58

Symbian OS: Coding Conventions in C++ | 5

4.3.2  Use caution with array granularities .....................................................................52 4.3.3  Avoid global data..................................................................................................52 4.3.4  Beware of base class member data.....................................................................53 4.3.5

 Use the cleanup stack correctly ...........................................................................53

 4.3.6  Delete early ..........................................................................................................53 4.3.7  Test on hardware with the maximum data set......................................................53 4.3.8  Break up long, complex operations......................................................................53 

4.4  Reducing Stack Usage..................................................................................................53 4.4.1  Use descriptors correctly......................................................................................53 4.4.2  Beware of recursion, and build in limits................................................................54 4.4.3  Beware of logging code........................................................................................54 

4.5  Low Disk Handling ........................................................................................................54 5.  Building for ARM Targets................................................................................. 55 

5.1  General Issues..............................................................................................................55 5.2  Function Exports ...........................................................................................................55 5.3  The "MyDll.DLL has (un)initialized data" error from PETRAN......................................55 

6.  Terms and Abbreviations ................................................................................. 58 

Version 1.0 | May 5, 2004

Page 6: Symbian OS Coding Conventions v1 0 En

8/4/2019 Symbian OS Coding Conventions v1 0 En

http://slidepdf.com/reader/full/symbian-os-coding-conventions-v1-0-en 6/58

Symbian OS: Coding Conventions in C++ | 6

Change History

May 5, 2004 Version 1.0 Replaces documents Coding Idioms for Symbian OS C++ Programmers v1.0 and

Coding Idioms for Series 60 Developers v1.1 

Version 1.0 | May 5, 2004

Page 7: Symbian OS Coding Conventions v1 0 En

8/4/2019 Symbian OS Coding Conventions v1 0 En

http://slidepdf.com/reader/full/symbian-os-coding-conventions-v1-0-en 7/58

Symbian OS: Coding Conventions in C++ | 7

1 . I n t ro d u c t i o n

1.1 Purpose and Scope

This document is aimed at all developers who use the C++ language to developapplications for Symbian OS C++ programming. The purpose of this document is toassist designers in the task of C++ programming. All software authors are expected toadopt the conventions detailed here as standards.

The apocryphal 80-20 development rule states that 80 percent of the time will be spentfixing 20 percent of the problems that occur in development. This document addressesthat problematic 20 percent.

1.2 Motivation

Programming style can be described as, "The way that a programmer brings clarity,maintainability, testability, reliability, and efficiency to the code of a module."

This definition sets the objectives for good programming style but it does not help todetermine whether a piece of software has good or bad style. One can easily concludethat coding itself is only one factor in reaching these goals: a badly designed module canhardly be clear, maintainable, testable, or reliable, even if it is coded in the best possiblestyle. On the other hand, even the most excellent design cannot make the software clear and maintainable if its implementation, the code, is of poor quality.

In a software platform, the programmers must have a similar style, otherwise softwaremaintenance is too expensive and difficult, and reuse becomes almost impossible. A

uniform way of coding contributes strongly to the programming productivity of theorganization.

1.3 Document Outline

The first part of the document introduces the coding convention; this is followed bypractical coding idioms that provide beginners with a good understanding of Symbian OSC++ programming. The last part of the document addresses system resource usage.

Version 1.0 | May 5, 2004

Page 8: Symbian OS Coding Conventions v1 0 En

8/4/2019 Symbian OS Coding Conventions v1 0 En

http://slidepdf.com/reader/full/symbian-os-coding-conventions-v1-0-en 8/58

Symbian OS: Coding Conventions in C++ | 8

2 . C o d i n g C o n ve n t i o n s

This section will describe how to write good-style Symbian OS C++ applications.

Although not strictly required for writing good Symbian OS applications, it is goodsoftware practice for all programmers. A good programming style can greatly improvereusability, maintainability, and readability. Once a convention is defined, it should beused consistently among all programmers in the team and all applications.

2.1 General Principles

For clear and maintainable code, certain general rules can be applied to all languages.

2.1.1 Reusability

Avoid rewriting or copying code that someone else has written. Identify a needfor a common module (or component) that you and others might require andcommunicate the need forward to other persons in your project. You or someoneelse should create a well-designed, well-documented, and well-testedcomponent. For example, file system dialogs, formatters, and checking routinesare good candidates to be grouped into common modules. By creating commonmodules you can reduce the code size; however, remember that reusing aninsufficiently documented or tested module can sometimes be very expensive.

Make sure the code can protect itself against misuse. If this is not possible,remember to document all restrictions, especially error codes returned bymethods. Comments in code can make the code more understandable andeasier to read. However, if the code needs at lot of explanation, it is probably notclear enough.

2.1.2 Maintainability

One of the properties of good code is that it is understandable and easy to read.If/when code needs to be maintained, it can be a very difficult and time-consuming job if the maintenance person does not understand what the codedoes. Thus, when writing code you should always ask yourself how others willunderstand it. From a software development management point of view, the idealscenario would be if the code developed by one person could be taken over byanother person without difficulty. If the code of a module becomes too long or complex, check to see whether the module should be reorganized.

2.1.3 Build process

There must be a well-known, very good reason to ignore warnings. A commonheader file should suppress warnings that should genuinely be suppressedthroughout the system. Use PC-Lint or a similar source code checker to makeadditional checks on code to catch some of the bugs, inconsistencies, andoversights.

2.1.4 Internationalization

Internationalization means designing and coding software to allow for localizationand smooth production of language variants with a minimum of engineering

changes. Internationalization aims at single code base.

Version 1.0 | May 5, 2004

Page 9: Symbian OS Coding Conventions v1 0 En

8/4/2019 Symbian OS Coding Conventions v1 0 En

http://slidepdf.com/reader/full/symbian-os-coding-conventions-v1-0-en 9/58

Symbian OS: Coding Conventions in C++ | 9

2.1.5 Specific Symbian OS issues

Symbian OS is designed to deliver high-function applications in a very resource-constrained environment. Robustness is critical to end-user acceptance of portable devices. The Symbian OS resource management and cleanup

framework provides a robustness and scalability unparalleled in this applicationsector.

Note: Every programmer should be familiar with the cleanup and memorymanagement issues of Symbian OS. The important issues in coding arereliability, size, and speed, in that order.

2.2 Source Files

2.2.1 General issues

Never use white space or non-ASCII characters in file names. Also, thefollowing characters are not allowed: & ^ + - @ $ % * ( ) | \ / [ ] { } < > ? ; : , " '

Write file names in lowercase, but with the first letters of words capitalized.Write file names as if they were case-sensitive so that they are spelledidentically in the file system and in source code files.

Do not, however, rely on case-sensitivity in file names. In other words, do notname two different files so that their names differ only by upper-/lowercaseletters. (Example: If file "CallEdit.h" already exists, do not name another file "CalledIT.h").

References to physical file system paths must not be used.

When adding a new class into an existing library, always use a separate filefor the class. Only tiny helper classes can be located together with their mainclass.

When writing applications, the engine, views, and main application codeshould be written in separate files. If it is probable that a single engine will beaccessed simultaneously by multiple applications, consider implementing aclient/server interface.

Machine- or compiler-dependent parts of code are isolated in separate files.

Header files are kept in the directory ".\inc" or in directories mentioned inthe bld.inf file.

Private header files located in the process or library directory of the sameproject are enclosed in quotation marks ("") in #include directives. Publicheaders are enclosed in angle brackets (<>).

Version 1.0 | May 5, 2004

Page 10: Symbian OS Coding Conventions v1 0 En

8/4/2019 Symbian OS Coding Conventions v1 0 En

http://slidepdf.com/reader/full/symbian-os-coding-conventions-v1-0-en 10/58

Symbian OS: Coding Conventions in C++ | 10

2.2.2 File types

2.2.2.1 File name extensions

The following file name extensions are used for source and binary files:

File nameextension

Description

h C++ header file

.inl C++ inline function implementation file

.hrh Common header file for resources and C++ programs

.cpp C++ source file

.mmp Symbian OS project specification file (for makmake)

bld.inf Build information file

.mak Makefile

.rh Resource header file

.rss Resource file

.loc Localization string resource header file

.rsc Compiled resource file (no language specified)

.rXX Compiled resource file (XX is the language specifier)

.bmp Windows bitmap file

.mbm Symbian OS multibitmap file

.aif Symbian OS application information file

.app Executable Symbian OS application, polymorphic DLL

.dll Shared library DLL

.exe Symbian OS server or executable program

Table 1: File name extensions used for source and binary files

2.2.2.2 C++ header file (.h)

Header file comments are written for the user of the module. They areadequate if the test cases for the module can be drawn up on the basis of them; see Section 2.5, “Commenting Conventions.”

Write one class in one header file. Only tiny helper classes may be groupedtogether with their "parent" class.

Add #ifndef CLASSNAME_H and #define CLASSNAME_H statements in thebeginning of a header to protect it against multiple includes from other files.

This anti-nesting mechanism prevents multiple inclusions of the header files.

Version 1.0 | May 5, 2004

Page 11: Symbian OS Coding Conventions v1 0 En

8/4/2019 Symbian OS Coding Conventions v1 0 En

http://slidepdf.com/reader/full/symbian-os-coding-conventions-v1-0-en 11/58

Symbian OS: Coding Conventions in C++ | 11

Note: The #ifndef XXX form of the guard against multiple inclusion issignificantly quicker than the apparently equivalent #if !defined(XXX) form.

Inside a header file include only those other header files that are required for 

class definition or to use the class. Do not use #ifndef statements whenincluding other header files.

Remember to use your own prefix (e.g., CTetrisAppUi) in class names.

Forward declarations are preferable to #include statements. If the class isaccessed only via pointers or references, it should not be included with#include. Including unnecessary header files may very easily increase buildtime and object file size significantly. Most #include statements are actuallyunnecessary. It is often adequate to forward-declare the class.

Wrong:

// MyClass.h

// This pollutes include-hierarchy:#include “OtherClass.h”

class CMyClass: public CBase{...private:

COtherClass* iPointer;};

Including "OtherClass.h" is unnecessary, but pollutes the include hierarchyfor "MyClass.h". A better solution would be:

Example:

// MyClass.h

class COtherClass;

class CMyClass: public CBase{...private:COtherClass* iPointer;};

Note that now only "MyClass.cpp" has to include "OtherClass.h". Other modules using just "MyClass.h" never need "OtherClass.h".

Place constructors and destructors at the beginning.

Place data members at the end.

Always use separate sections for derived methods and add comments todescribe where they have been inherited from.

Do not implement inline methods in a header file. Put them into a separate.inl file.

Use standard headers, giving standard information; be consistent; for example:

// EXAMPLE.H// Copyright (c) 2003 Symbian Ltd. All rights reserved.

// Example module header//

Version 1.0 | May 5, 2004

Page 12: Symbian OS Coding Conventions v1 0 En

8/4/2019 Symbian OS Coding Conventions v1 0 En

http://slidepdf.com/reader/full/symbian-os-coding-conventions-v1-0-en 12/58

Symbian OS: Coding Conventions in C++ | 12

2.2.2.3 C++ source file (.cpp)

Implementation file comments are written for the maintainer of the module.They are adequate if they meet the following requirements:

o They describe class level implementation and clarify all the nontrivialissues.

o Member function comments cover explanations for all the nontrivialimplementation code. Other functions must also contain parameter andreturn value comments.

o Be consistent in the use of programming conventions.

Write the implementation of one class in one file.

Methods should be defined in the same order as in the header file.

Use the same names for the method parameter as you have used in the

header file.

2.2.2.4 Resource file (.rss)

Remember all the necessary #includes for your resource structures.

Use a unique NAME identifier (maximum length is four characters).

Place enums in .hrh and resource structures in .rh.

Write resource names in lowercase; the resource compiler generatesuppercase identifiers for C++ programs automatically.

Do NOT put strings to be localized into resource files. Use logical names inresource files and put the actual strings in a separate resource header file(.loc), i.e., not to the same header file as resource structures.

If you are using a TBUFnn variant, e.g., TBUF80 or TBUF64, and you areloading the string into a local TBuf<nn> variable, ensure that both "nn"s areequal. This prevents nasty buffer overflows at run time. The preferred way isto use pure TBUF and use StringLoader::Load or iEikonEnv->AllocReadResourceLmethods in your code.

2.2.2.5 Common header file (.hrh)

The common header file must meet both C++ and resource file syntax.

Usually only control IDs, defines, and enums must be placed in the commonheader file.

Resource IDs will be collected automatically into filename.rsg and mustnot be defined in the .hrh file.

Resource structure definitions must be in the .rh file — they do not meet C++syntax and thus cannot be compiled by the C++ compiler.

2.2.2.6 Localization string resource header file (.loc)

The localization file lists all of the logical names (actually C macros) for textsto be localized.

Version 1.0 | May 5, 2004

Page 13: Symbian OS Coding Conventions v1 0 En

8/4/2019 Symbian OS Coding Conventions v1 0 En

http://slidepdf.com/reader/full/symbian-os-coding-conventions-v1-0-en 13/58

Symbian OS: Coding Conventions in C++ | 13

Use comments in the .loc file to facilitate easy localization. Comments shouldbe descriptive; describe the functionality of the text item in English.

Note: For common and generic texts, check if it already exists in avkon.loc,

and use the text string from AVKON. Avoid duplicate and overlapping textitems.

2.2.2.7 Project specification file (.mmp)

Note: Use the LANG SC statement to allow for conditional software builds.Using LANG SC allows for adding new language variants without having toupdate .mmp files.

2.3 Language

2.3.1 Naming and writing conventions

Note: These rules follow Symbian OS naming conventions. For further information, please see Symbian OS SDK documentation.

Use descriptive names for identifiers. If you cannot name an identifier,consider whether it has the right to exist at all. In general, the first letter of words should be capitalized for functions (exceptions noted explicitly).

Use full English descriptors that accurately describe the variable/field/class/.For example, use names like firstName, grandTotal, or CorporateCustomer. Although names like x1, y1, or fn are easy to typebecause they’re short, they do not provide any indication of what theyrepresent and result in code that is difficult to understand, maintain, andenhance.

Use terminology applicable to the domain. If your users refer to their clientsas customers, then use the term Customer for the class, not Client. Manydevelopers will make the mistake of creating generic terms for conceptswhen perfectly good terms already exist in the industry/domain.

Use mixed case to make names readable. Use lowercase letters in general,but capitalize the first letter of class names and interface names, as well asthe first letter of any noninitial word.

Use abbreviations sparingly and intelligently. Maintain a list of standard shortforms (abbreviations), choose them wisely, and use them consistently. For example, if you want to use a short form for the word number, then choosenbr, no, or num; document the one you choose (it doesn’t really matter whichone); and use only that one.

Avoid long names (less than 15 characters is a good idea). Although theclass name PhysicalOrVirtualProductOrService might seem to be agood class name at the time (an extreme example), this name is simply toolong and you should consider renaming it to something shorter, perhapsOffering.

Avoid names that are too similar or differ only in case. For example, thevariable names persistentObject and persistentObjects should notbe used together, nor should anSqlDatabase and anSQLDatabase.

Version 1.0 | May 5, 2004

Page 14: Symbian OS Coding Conventions v1 0 En

8/4/2019 Symbian OS Coding Conventions v1 0 En

http://slidepdf.com/reader/full/symbian-os-coding-conventions-v1-0-en 14/58

Symbian OS: Coding Conventions in C++ | 14

Capitalize the first letter of standard acronyms. Names will often containstandard abbreviations, such as SQL for Standard Query Language. Namessuch as sqlDatabase for an attribute or SqlDatabase for a class are easier to read than sQLDatabase and SQLDatabase. 

All names should be in English, because the reserved words of theprogramming language are in English, too. In addition, in an internationalorganization, English is usually the only language everybody understands.

Write all words adjoined, for example "LikeThis".

Avoid numbers and abbreviations in names.

Never use _ (underscore). The only exception is _ as a delimiter inpreprocessor macro names in #define; see Section 2.3.1.6, “Macros andother #defines.”

void TObject::PrepareForCommit();class CGlobalText; // see note on class names and types

TInt elementOffset; // automatic variables begin in lowercase 

Function, class, typedef, struct, and method names begin with anuppercase letter.

Using automatic variables

o All automatic variable names begin with a lowercase letter.

o Do not declare automatics until required (avoid the Kernighan and Ritchie(K&R) C style of declaring all the automatics used in a routine at the topof that routine).

o Always try to initialize variable when they are declared rather than

assigning values to them.

o Never initialize or instantiate multiple items on the same line.

Example:

TInt CTetrisClass::Function() // Member function{TInt automaticVariable( KInitialValue ); // Integer variableTBool status( IsItTrue() ); // Boolean variableiMemberClass.Method(); // Calls a method...}

Wrong:

TBool Variable = is_it_true();// Wrong type specifier, name of an automatic variable// mistyped, assignment used instead of initialization and name// of a function miswritten.

Explanation: Having the first letter of the automatic variable lowercase issimply a convention to help reviewers and maintainers follow your code.

The main reason for not declaring automatics until required is because theymay not be required; declaring them at the start of a routine is thereforeinefficient in terms of execution speed and use of stack space.

For lengthy routines, declaring automatics as close as possible to the point of use can also help people understand code fragments without having to refer 

back to the top.

Version 1.0 | May 5, 2004

Page 15: Symbian OS Coding Conventions v1 0 En

8/4/2019 Symbian OS Coding Conventions v1 0 En

http://slidepdf.com/reader/full/symbian-os-coding-conventions-v1-0-en 15/58

Symbian OS: Coding Conventions in C++ | 15

Initializing variables when they are declared is more efficient (smaller andfaster code) and avoids the risk of using the variable in an uninitialized state.

Declaring multiple items on the same line can lead to errors such as:

TText* data1, data2;TInt int1, int2 = 0; 

when the programmer meant:

TText* data1;TText* data2;TInt int1=0;TInt int2=0; 

2.3.1.1 Class names

Class names consist of <Symbian OS prefix ><Project prefix >Name

The Symbian OS prefix is one of the following:

o C (heap-allocated class derived from a base class CBase)

o R (resource class containing handles to a real resource, which ismaintained elsewhere)

o T (simple type)

o M (mix-in class / interface class)

The class-naming distinction helps reinforce valuable programming idioms.For further information about the definition of the class types, please refer tothe SDK help.

Structs are T.

Exceptionally, driver classes known by the kernel are D classes. See theSymbian Developer Library for more information.

Use references in preference to pointers — if none of the criteria for usingpointers apply.

Pay attention to const; use const for parameters and return values if thedata is not to be modified.

Static classes have no prefix letter.

Example:

class MTetrisObserver; // Observer class (mix-in)/**Tetris game factory.*/class TetrisFactory // Static class

{public:

/** Returns new CTetrisItem object. */static CTetrisItem* NewItem();

...

Version 1.0 | May 5, 2004

Page 16: Symbian OS Coding Conventions v1 0 En

8/4/2019 Symbian OS Coding Conventions v1 0 En

http://slidepdf.com/reader/full/symbian-os-coding-conventions-v1-0-en 16/58

Symbian OS: Coding Conventions in C++ | 16

2.3.1.2 Functions

Parameter names have an a prefix.

Parameter names must be mentioned in both declaration and definition. If 

some parameter is not referenced inside the function, its name can beomitted from the definition.

Example:

// tetrisc.h:/**Base class of Tetris game.*/class CTetrisClass : public CBase

{public:

/*** Initializes a game.* @param aNumber Difficulty level.* @return Status code (0 is success, -1 is error).*/

TInt MemberFunction( TInt aNumber );...

// tetrisc.cpp:...// --------------------------------// CTetrisClass::MemberFunction// Implementation description.// --------------------------------TInt CTetrisClass::MemberFunction( TInt aNumber )

{...}

Use a const attribute where appropriate to indicate that a method does notchange the state of an object or a parameter, which is read-only.

Ellipsis notation is forbidden.

Example:

TInt Add( const TInt aFirstNumber, const TInt aSecondNumber );

Wrong:

TInt BadFunction( ... );// Ellipsis notation must not be used

A trailing L indicates that function or method might leave. It is very importantto know whether or not a function might leave.

A trailing C indicates that a function or method places one item on thecleanup stack and leaves it there. The caller must pop the item later from thecleanup stack.

A trailing D indicates that the method will destroy the object in question.

Example:

static CTetrisClass* NewLC(); // May leave and place an it

// the cleanup stackTInt ExecuteLD( TInt aResourceId );// May leave and will destroy

// the object (in this case, it// will destroy the dialog after

// use)

Version 1.0 | May 5, 2004

Page 17: Symbian OS Coding Conventions v1 0 En

8/4/2019 Symbian OS Coding Conventions v1 0 En

http://slidepdf.com/reader/full/symbian-os-coding-conventions-v1-0-en 17/58

Symbian OS: Coding Conventions in C++ | 17

Wrong:

TInt MyFunction(){FunctionThatMayLeaveL();...

// If you call a function that may leave, you must either// state that MyFunction can leave too (using L-postfix) or// use TRAP-harness to catch the error that might occur.

Use the following naming convention when defining data exchange methods.Notice the const keywords:

Example:

TInt Width() const; returns a valueconst CHugeMatrix& Matrix() returns a referencevoid SetWidth( TInt aWidth ) changes the valuevoid GetWidth( TInt& aWidth ) const; returns a value in reference arg.

Wrong:

TInt GetCount();// “Get”-prefix is not used if function just returns the value.// “Count()” would be the correct name for this function.// Also "const" keyword is missing.

Encourage generality; use the least derived class possible.

Example:

void Foo(const CArrayFix<X>& aX); 

rather than:

void Foo(const CArrayFixFlat<X>& aX); 

2.3.1.3 When to use which form of parameter / return

By const value const X

o Don't do this; it only restricts the code in the implementation, and has noimpact on clients.

By value X

o For return values or arguments that are concrete data types or are small(< 8 bytes).

o For return values where the object has to be built (i.e., cannot return areference to one you have already); note that for large classes it ispreferable to use a reference argument to get a value, as this reducesstack usage.

By const reference const X&

o Do not do this for concrete (built-in) types, especially enumerations, asthe target (gcc) compiler will fault.

o Use for larger arguments (> 8 bytes).

o If in doubt, pass all class arguments using this form.

Version 1.0 | May 5, 2004

Page 18: Symbian OS Coding Conventions v1 0 En

8/4/2019 Symbian OS Coding Conventions v1 0 En

http://slidepdf.com/reader/full/symbian-os-coding-conventions-v1-0-en 18/58

Symbian OS: Coding Conventions in C++ | 18

By reference X&

o To allow a function to return values through these arguments, or modifythe contents of them.

o For return values, where the object exists and can be modified by thecaller; note the lifetime of the object being.

o Returned must extend beyond the scope of the function.

By const pointer const X*

o Const for items that can be used (but not modified) by the recipient; e.g.,a buffer.

o If a NULL (nonexistent) object is meaningful (so const X& cannot beused), i.e., the argument/return value is optional; if this is the case,consider using a function overload instead — one taking a reference andone taking no arguments — if it makes the API clearer.

By pointer X*

o For a modifiable (non-const) object that is optional; again, consider anoverload if it makes the interface more intuitive.

o To imply transfer of ownership, rather than just available for use (ownsvs. uses); the recipient of the object is now responsible for deleting theobject.

2.3.1.4 Member data

Use preceding i for  instance data.

DLLs must not have any global non-const data. This includes static member variables.

Example:

/*** Tetris game base class.*/class CTetrisClass: public CBase

{...private:

TInt iIntegerMember;COtherClass* iPointerToAnotherClass;

...

}

Wrong:

class BadClass{...// This member function is OK:EXPORT_C static TInt MemberFunction();...// But this data member isn’t:static TInt iStaticMember;// DLL’s can not have any global non-const data.

Version 1.0 | May 5, 2004

Page 19: Symbian OS Coding Conventions v1 0 En

8/4/2019 Symbian OS Coding Conventions v1 0 En

http://slidepdf.com/reader/full/symbian-os-coding-conventions-v1-0-en 19/58

Symbian OS: Coding Conventions in C++ | 19

2.3.1.5 Pointers and references

When declaring or defining pointers or references, place a specifier (* or &)next to type, not next to name.

Example:

CTetrisClass* pointer; // Pointer to CTetrisClassvoid Modify( TInt& aInteger ); // Reference parameter used 

Wrong:

CTetrisClass *badNotation;void Modify( TInt &aBadOne );

2.3.1.6 Macros and other #defines

Avoid macros in release code. Macros are interpreted using textreplacement, which is error-prone and never type-safe. Exception: Debugand test code often requires precompiler macros.

Write all letters capitalized.

Underscore ( _ ) separates words.

Avoid #defines; use real constants instead.

Example:

const TInt KMagicNumber = 42;

Wrong:

#define MAGIC_NUMBER 42// const TInt should be used

2.3.1.7 Constants

Use a K prefix in const names.

Do not pollute global namespace; use relevant prefixes in names.

Example:

const TInt KTetrisInitialBlockSize = 20;

2.3.1.8 Enumerated types

Enums should be scoped within the relevant class.

Do not pollute the global name space.

Enums and their members must have relevant, meaningful, and unambiguousnames.

Enumerations are types, therefore they have a T prefix.

Use an uppercase E prefix for enum members.

Class-specific constants can be implemented as enums and in that case are

K.

Version 1.0 | May 5, 2004

Page 20: Symbian OS Coding Conventions v1 0 En

8/4/2019 Symbian OS Coding Conventions v1 0 En

http://slidepdf.com/reader/full/symbian-os-coding-conventions-v1-0-en 20/58

Symbian OS: Coding Conventions in C++ | 20

Example:

class CTetrisBlock{...enum TTetrisBlockType

{ETetrisLBlock,ETetrisSquareBlock,...};

...};

2.3.1.9 Global variables

Use of global variables is discouraged.

Start with a capital letter. In cases where confusion might be caused (for instance, if the capital letter in question is an H, a T, or a C, and there's no

obvious alternative name), you may use a small g prefix, e.g. gWhatever 

In Symbian OS, DLLs must not have any global non-const data; it is better touse thread local storage (TLS).

2.3.1.10 Control structures

Every switch() statement must have a default: clause, at least for detecting unexpected switch expressions. Case branches without a breakstatement should be avoided. If one has to be used, the flow through must beexplicitly indicated by a comment.

Use always compound statement braces ({, }) in all of the control flow

statements, if() - else, while(), do - while() and for(), even if there was only a single statement or an empty block.

Example:

if ( error ){Panic();}

The control flow statements break, go to, and continue must not be used. Anexception: break should be used in case statements.

2.3.1.11 Exceptions and templates

C++ style exceptions must never be used.

Symbian OS provides TRAP-harness , which should be used to handle error conditions.

Avoid defining your own templates. If you have to, test them carefully on thetarget platform. Keep in mind that different C++ compilers have differentproblems with templates.

Handle all errors.

Version 1.0 | May 5, 2004

Page 21: Symbian OS Coding Conventions v1 0 En

8/4/2019 Symbian OS Coding Conventions v1 0 En

http://slidepdf.com/reader/full/symbian-os-coding-conventions-v1-0-en 21/58

Symbian OS: Coding Conventions in C++ | 21

2.4 Indenting Conventions

2.4.1 Spacing

All C++ statements within a block of code should be indented exactly four spaces deeper than the enclosing block.

Configure your editor so that it uses spaces instead of tab characters. Notethat some editors are not able to show possibly existing tabs.

Primary operators should be written with no spaces around them. Primaryoperators are:

o lvalue.id

o var.*ptr

o table[index]

o pstruct->id

o pstruct->*id

Unary operators should be written with no spaces between them and their operands. Exceptions: new and delete.

All other operators should be written with one space on each side of theoperator.

Example:

if ( iPointer->Method() > KOurMaxValue )

{iCounter++;variable = iTable[a] + iOffset;}

2.4.2 Placement of braces and parentheses

The placement of the { and } braces must be at the same level of indentationas the code they are enclosing. Note that some editor tools can beconfigured to indent the code according to this rule.

There should be a maximum of 80 characters per line. Longer lines are hardto read and some editors cannot handle them properly. Longer lines are splitinto several lines, for example:

class CMessageListView:public CPknView,public MEikListBoxObserver,public MmsvSessionObserver 

or:

void DoActivateL(const TVwsViewId& aPrevViewId,TUid aCustomMessageId,const TDesC8& aCustomMessage );

or:

if ( isThisIntegerNumber > 42 && isThisIntegerNumber < 142 &&somethingElse >= 0 ) 

Version 1.0 | May 5, 2004

Page 22: Symbian OS Coding Conventions v1 0 En

8/4/2019 Symbian OS Coding Conventions v1 0 En

http://slidepdf.com/reader/full/symbian-os-coding-conventions-v1-0-en 22/58

Symbian OS: Coding Conventions in C++ | 22

Matching parentheses should be written with matching spaces, e.g., if thereis no space on the inside of a ( then there must be no space on the inside of its matching ).

There must be no space between a function or macro name and its

parenthesized argument(s).

There must be a single space between a keyword (e.g., for, if) and itsparenthesized argument(s).

Example:

iMember.Method( first, second );if ( i < KtetrisMaxIterator ) ...

Wrong:

Modify(parameter );// Matching number of spaces should be used on both sides.if( error ) ...

// There should be one space between “if” and “(“.

Parentheses should always be used where there is potential ambiguity.

2.5 Commenting Conventions

2.5.1 General commenting conventions

Comments are written in English.

Other comments must be inserted into the code as it is being developed.They must appear with the relevant code.

Avoid commenting a matter in many places and avoid repeating code incomments.

Comments should explain why something has been done rather than whathas been done.

Choose C++ style comments ("// Comment") and avoid C style ("/* Comment*/").Exception: File header comments can be written in C style. Exception: Classand method header comments should be written in Javadoc style, as definedin Section 2.5.2, Class and method header file comments.

2.5.2 Comment layouts

A boxed comment has the following layout:

// ==============================// Boxed comment example.// ==============================

An exception is a file header comment where you can use C style comments.

A block comment has the following layout:

// Block comment example.// The second line of comment.//

Version 1.0 | May 5, 2004

Page 23: Symbian OS Coding Conventions v1 0 En

8/4/2019 Symbian OS Coding Conventions v1 0 En

http://slidepdf.com/reader/full/symbian-os-coding-conventions-v1-0-en 23/58

Symbian OS: Coding Conventions in C++ | 23

Block comments should be indented so that the opening / (back slash) isaligned with the first line of code to which it refers. The comment is placedbefore the code it describes.

An appended comment consists of a few words on the same line as the item

to which it relates.

If ( aColour == KRgbRed ) // Is it red?

A file header comment has the following layout. Note that the Interface part,which is used to categorize APIs, is used only in .h files. If the category of the API has not been set, it should be left empty.

/** =============================================================* Name : ?FileName.h* Part of : ?Subsystem_name / ?Module_name* Interface : ?Interface_category, ?Interface_name* Description : ?Description* Version : ?Version

** Copyright (c) 2002 Nokia Corporation.* This material, including documentation and any related* computer programs, is protected by copyright controlled by* Nokia Corporation. All rights are reserved. Copying,* including reproducing, storing, adapting or translating, any* or all of this material requires the prior written consent of* Nokia Corporation. This material also contains confidential* information which may not be disclosed to others without the* prior written consent of Nokia Corporation.* =============================================================*/

Class and method header file comments have the following layout:

/**

* Short class description goes here ending with dot.* Second sentence is here.* Third sentence is here.*/class CMyClass : public CBase

{public:

/*** Method header documentation goes here.* @since 2.0* @param I Parameter description.* @return Description of the returned value*/TInt MyMethod( Tint I );...

}

2.6 Data Types and Usage

Note: Most of these rules have been adapted from Symbian OS SDK andSymbian OS coding conventions.

2.6.1 Constants

Never use hard-coded constants, such as "magic numbers," in your code. Useenums, resources, and real const definitions instead.

Version 1.0 | May 5, 2004

Page 24: Symbian OS Coding Conventions v1 0 En

8/4/2019 Symbian OS Coding Conventions v1 0 En

http://slidepdf.com/reader/full/symbian-os-coding-conventions-v1-0-en 24/58

Symbian OS: Coding Conventions in C++ | 24

Example:

switch ( aCommand ){case ETetrisDropBlock:

...

break;case EEikCmdExit:

...break;

default:// Handle unexpected CommandID here....

}

Avoid preprocessor macros (#defines).

Collect your const and enum definitions to a single place so that they can beeasily spotted for changes.

If the interface of the class itself uses enum values (for example, as defaultarguments), the enum values must be defined before they are used in afunction declaration.

Always use a predefined library constant if one exists.

Never define a string constant. Use a resource file instead. As an exception,string constants may be used where they do not appear on the UI and arenot language-dependent, e.g., protocol strings, resource names, system filenames.

Never define a color constant of your own. Use a predefined library constantinstead. 

Example:

const TRgb KTetrisBgColor( KRgbBlack );...

TRgb backgroundColor( KTetrisBgColor );

2.6.2 Variables

Initialize variables when you create them. Use initialization instead of assignment when it is more effective.

Never initialize or instantiate multiple items on the same line.

Do not declare automatic variables until required.

Never use static local variables.

Example:

TRect rectangle( 0,0,0,0 );CTetrisClass* pointer = NULL;

Wrong:

static int a, b, c;// Static local variables are not allowed, TInt type must be// used, variables should be initialized (to zero, for example)// and multiple items should not be declared on the same line.

Version 1.0 | May 5, 2004

Page 25: Symbian OS Coding Conventions v1 0 En

8/4/2019 Symbian OS Coding Conventions v1 0 En

http://slidepdf.com/reader/full/symbian-os-coding-conventions-v1-0-en 25/58

Symbian OS: Coding Conventions in C++ | 25

2.6.3 Types

Never use primitive types (such as int, char, float, double, or bool)directly. Instead, use concrete types provided by Symbian OS.

Note that TBool is ETrue or EFalse but in an if() statement you shouldnever compare it to any exact value.

Example:

TBool booleanVariable( EFalse );...

if ( booleanVariable ) // Is it true?...

Use descriptors (TDes, TPtr) and buffers (HBuf, TBuf) instead of ordinarypointers when storing data and handling strings.

2.6.4 Typecasting

Casts, as in other operating systems, should be used with caution. If a castseems to be needed, check that this does not reflect a design weakness.

Prior to Symbian OS v6.0, gcc did not support the C++ casting operators, andhence Symbian OS defined macros as simple C style casts for that compiler:REINTERPRET_CAST , STATIC_CAST, CONST_CAST, MUTABLE_CAST.

From Symbian OS v6.0 onwards gcc fully supports the C++ casting operators,and the macros have been changed to reflect this in Symbian OS v6.1. Thismeans that from Symbian OS v6.0 onwards, developers should use the nativeC++ casting operators rather than the macros.

The more sophisticated C++ dynamic_cast operator should not be usedbecause EPOC does not enable or support Run Time Type Information(RTTI).

Use explicit typecasts to clarify your code and to avoid problems caused byunexpected implicit casts, such as integral promotions.

Example:

TUint16 wd( TUint16( TUint16( aPlace[aIndex] ) * TUint16(0x100) ) );// This is the right way to do it without compiler warnings.

Avoid casting to any type that has a different size than the original.

Avoid removing a const attribute.

Use a separate cast for constness and representation. In case astatic_cast or a reinterpret_cast to a non-const type is used, whoseargument is a const object of an otherwise appropriate type, use anadditional const_cast to the argument in question.

Typecast from a derived class to a base class is, in most cases, implicit. If anexplicit cast is needed or if you need to cast from a base class to a derivedclass, use static_cast<type>(exp).  

Version 1.0 | May 5, 2004

Page 26: Symbian OS Coding Conventions v1 0 En

8/4/2019 Symbian OS Coding Conventions v1 0 En

http://slidepdf.com/reader/full/symbian-os-coding-conventions-v1-0-en 26/58

Symbian OS: Coding Conventions in C++ | 26

Example:

class CDerived : public CBase...

CBase* basePointer = NULL;basePointer = new CBase;

...CDerived* derivPointer = NULL;derivPointer = static_cast<CDerived*>(basePointer);// Note that you must be sure that basePointer really contains a// pointer to CDerived object. Dynamic cast isn’t supported ! 

Typecasting between any other incompatible type must be done with areinterpret_cast(type,exp) macro. See the ANSI C++ sectionexpr.reinterpret.cast for a description of permitted conversions.

Never break 4-byte alignment with any typecast!

2.6.5 Pointers

Never return a pointer or a reference to any local data.

Wrong:

TInt& AddFive( TInt aNumber ){TInt result( aNumber + 5 );return result; // Whoops, local reference returned}

Initialize the pointer to NULL, not zero. In an if() statement, you shouldnever compare any pointer to any exact value.  

Example:

CTetrisClass* tetrisPointer = NULL;...

if ( tetrisPointer ) // Check if it points to an object...

Assign or initialize a pointer to NULL every time, when it does not point toany existing object.

2.7 Objects and Classes

Note: For further information, please see Symbian OS SDK documentation.

2.7.1 Class behavior 

Every class must have a default constructor and a destructor .

Whenever possible, declare the default constructor , a copy constructor, andan assignment operator as private in order to prohibit accidental access tothem.

Note that a C++ default constructor must not contain any code that canleave.

Version 1.0 | May 5, 2004

Page 27: Symbian OS Coding Conventions v1 0 En

8/4/2019 Symbian OS Coding Conventions v1 0 En

http://slidepdf.com/reader/full/symbian-os-coding-conventions-v1-0-en 27/58

Symbian OS: Coding Conventions in C++ | 27

Example:

/*** A tiny class.*/class TinyClass

{public: // Constructors and destructor

virtual ~TinyClass();

private:TinyClass();

// Prohibit copy constructor and assignment operator// in our class not derived from CBase.TinyClass( const TinyClass& aSource ); // copy constructorTinyClass& TinyClass::operator=(

const TinyClass& aParam );};

/**

* A tiny class based on CBase.*/class CTinyClass: public CBase

{public: // Constructors and destructor

virtual ~TinyClass();

private:TinyClass();

// CBase prohibits copy constructor or assignment operators.// No need to do it here.

};

Every class that owns any pointers requires two-phase construction.

class CComplexClass : public CBase{public: // Constructors and destructor

...static CComplexClass* NewL();static CComplexClass* NewLC();

private:CComplexClass();void ConstructL();

...};

An assignment operator must handle self-assignment.

Example:

const CMyClass& CMyClass::operator=( const CMyClass& aParam ){if ( this == &aParam )

{return *this;

}...}

Every time you allocate an object, you must ensure that it is destroyedcorrectly.

The same program entity (e.g., class) that allocates memory releases it,too.

Version 1.0 | May 5, 2004

Page 28: Symbian OS Coding Conventions v1 0 En

8/4/2019 Symbian OS Coding Conventions v1 0 En

http://slidepdf.com/reader/full/symbian-os-coding-conventions-v1-0-en 28/58

Symbian OS: Coding Conventions in C++ | 28

After deleting an object, assign a NULL value to it to prevent later attempts todelete a nonexisting object. Exception: In the destructor it is not necessary tonullify a deleted member pointer.

Example:

CMyClass::~CMyClass(){delete iAnotherClass;}

CMyClass::SomeMethod(){// …delete iAnotherClass;iAnotherClass = NULL;// …}

Do not use any global or static data in constructors or destructors.

Avoid using friend functions or classes.

Always write access-control specifiers; this removes all ambiguity.

List the public methods first, with special member functions at the top.

List public member data before private member data (otherwise, changingthe private data would break binary compatibility).

Use explicit access specifiers at the start of each class section:

o friend classes

o public methods

o protected methods

o private methods

o public data

o protected data

o private data

Heed binary compatibility issues with respect to promoting functions' accesscontrol specifiers; (if you change the access for something after an APIfreeze, you may have to leave it in exactly the same place as before).

Use white space to group related functions and improve readability.

Function arguments are named in the function declaration (as well as thedefinition); this improves readability.

Obey the indentation conventions.

2.7.2 Class interfaces

Avoid declaring public data. Use data exchange methods and private data members instead.

Interface member functions ( public methods) should not usually return a non-

const reference or pointer to a member variable. Returning handles tomember data breaks object encapsulation.

Version 1.0 | May 5, 2004

Page 29: Symbian OS Coding Conventions v1 0 En

8/4/2019 Symbian OS Coding Conventions v1 0 En

http://slidepdf.com/reader/full/symbian-os-coding-conventions-v1-0-en 29/58

Symbian OS: Coding Conventions in C++ | 29

If you return a pointer or a reference, remember that the lifetime of the objectbeing returned must always extend beyond the scope of the function!

Arguments of class type should be passed to functions by reference.

Example:

TInt MatrixWidth( const CHugeMatrix& aParam );

In the public API, pointer arguments imply passing ownership, and referencearguments imply usage only.

List the public methods first, with special member functions, such asconstructors and destructors, at the beginning.

Use explicit access specifiers at the start of each class section.

Example:

class CMyClass : public CBase{public: // Constructors and destructor

...public: // New functions

...public: // from CBase

...private: // New functions

...};

Use line feeds to group related functions and improve readability.

Do not implement member functions in the class declaration. Inline functionsare implemented in a separate .inl file.

Do not define unnecessary variables as member variables. If you need somevariable, only temporarily allocate it either from stack or heap and delete itafter you do not need it anymore.

Never push member data on the cleanup stack since this may create adouble deletion.

2.7.3 Virtual member functions

The destructor is always virtual.

The constructor (one or two phased) is never virtual.

Virtual functions that replace inherited behavior must be grouped together inthe header, with a comment documenting which class the behavior isinherited from.

Specify the virtual keyword only when you declare a new member function, not when you replace an inherited one.

Never make virtual functions inline; it is difficult to know exactly how acompiler treats these, and can lead to code bloat. Exception: Destructorsmay be inline.

2.7.4 Inline member functions

Specify inline explicitly for inline functions. Do not leave it to the compiler.

Version 1.0 | May 5, 2004

Page 30: Symbian OS Coding Conventions v1 0 En

8/4/2019 Symbian OS Coding Conventions v1 0 En

http://slidepdf.com/reader/full/symbian-os-coding-conventions-v1-0-en 30/58

Symbian OS: Coding Conventions in C++ | 30

Do not provide the inline implementation in the class definition; this confusesand pollutes the header, making it less readable.

Implement inline functions in a distinct file included by the header (.inl). 

Inline functions must be small; typically they just get or set a member variable, which has the amount of one or two machine word data.

2.7.5 Multi-inheritance

Only M classes may be used in multi-inheritance.

Only the interface may be inherited. Therefore all M classes must be purevirtual .

Inherit from the CBase-derived class first to achieve the correct layout of thev-table.

Example:class CDerivedClass : public CBase, public MSomeObserver

M classes may only be derived from other M classes.

2.7.6 Cleanup stack

Use the cleanup stack in preference to TRAP harnesses where appropriate.

Deriving a class from CBase provides support for using the cleanup stack.For other classes you can provide explicit cleanup support via theTCleanupItem class.

Never push member data on the cleanup stack.

2.8 Internationalization Coding Guidelines

This chapter gives guidelines on how to create code that can be localized to variouslanguages and regions most easily and efficiently, minimizing engineering changes.

Divide the project deliverables and any configurable resources into those that mayrequire localization and those that will not. These will include, for example, texts thatneed to be translated and graphical images that may require localization. They alsorequire layout rules. If in doubt, allow for localization.

The rule of thumb for implementation: Do not hard code anything that is visible in theuser interface. For example, the following items must be in a separate resource file:

All the texts visible in the user interface (including application names). Thesego into .loc files.

File names

Sounds

Time and date

Etc.

Version 1.0 | May 5, 2004

Page 31: Symbian OS Coding Conventions v1 0 En

8/4/2019 Symbian OS Coding Conventions v1 0 En

http://slidepdf.com/reader/full/symbian-os-coding-conventions-v1-0-en 31/58

Symbian OS: Coding Conventions in C++ | 31

2.8.1 Descriptors and character sets

All Symbian OS builds are Unicode, and descriptors containing an internalrepresentation of text will be 16-bit strings. Internally, Symbian OS usesUCS-2 (Little Endian). Class names such as TPtr should be used in code;

objects of this class will be built as objects of the class TPtr16.

Use explicit 8-bit versions of descriptors such as TPtr8 to hold binary dataor text in external character sets.

Use the CCnvCharacterSetConverterclass to convert text between theinternal Unicode representation and externally used character sets. A uniqueidentifier is assigned to each of the commonly used character sets; theCCnvCharacterSetConverter object will convert text between thespecified character set and Unicode.

2.8.2 Text

2.8.2.1 Logical name

The logical name convention demands that all logical names are uniquethroughout the software.

The same logical name should not be used for two different functions andlayouts, even though the string might be the same in English.

For example, On and Off are always the same in English. In Italian, "On" canbe translated as Attivo, Attiva, Attive, Attivi , Attivato, Attivata, Attivate, Attivati , or Si . Respectively, the same number of translation options isapplicable for the term "Off" — the translation depends on the context.

Where you have to make decisions about the length of resource strings,allow at least 30 percent headroom for translated text in general, but if thestring is a single word then make allowance for at least 100 percentexpansion in the translation whenever possible. This is all because thedevelopment language is English, which itself uses reasonably short words.

2.8.2.2 String 

Avoid dynamic or run-time concatenation of different strings to form newcompound strings (e.g., composing messages by combining frequently usedstrings).

Example:

qtn_common_new "new"

qtn_msg_message " message"

qtn_msg_received " received"

In Finnish, "new message received" can be translated uusi viesti saapunut , but if the string qtn_common_new was used for "3 new messages received," thetranslation would not work, as it should read "3 uutta viestiä saapunut," that is,two of the words are inflated. Note that in this example, if the same string "new"is used in the beginning of a concatenated text, in languages where there isdistinction made with the casing, lowercase would simply be wrong in the

beginning of the text item displayed on the UI.

Version 1.0 | May 5, 2004

Page 32: Symbian OS Coding Conventions v1 0 En

8/4/2019 Symbian OS Coding Conventions v1 0 En

http://slidepdf.com/reader/full/symbian-os-coding-conventions-v1-0-en 32/58

Symbian OS: Coding Conventions in C++ | 32

2.8.2.3 Style

Avoid using a style of text for a particular purpose to make a definitedistinction. Most non-Latin-based writing systems do not make a distinctionbetween upper- and lowercase, or the italics type face may be missing.

Do not use folding to achieve a lowercase or uppercase effect; instead, useTChar::UpperCase or TChar::LowerCase for this purpose. Foldingremoves case distinctions, and also, by default, does many other things suchas removing accents and changing Hiragana to Katakana, which may not bedesired.

Text localized to a non-English language (e.g., German) can easily expandup to 100 percent. The general recommendation is to allow at least 30-50percent for horizontal expansion and 10-20 percent for vertical expansion.

2.8.3 Graphics and screen layout

Avoid using text in graphical UI elements because there may be instanceswhere the graphics need to be redrawn for new markets to take culturalrequirements into account. If text is really needed for graphics, a better solution would be to use a text string on top of graphics.

Do not hard code screen sizes (calculate the layout at run time).

2.8.4 Locale-specific data

The API of the class TLocale is documented fully in the Series 60 SDK. AllSymbian OS developers should be familiar with the class and it should be usedwhere appropriate to produce locale-independent code. The User class libraryalso possesses static functions, some of which are language-dependent. Theseinclude User::Language(),which returns the language of the current locale.

The hard-coded language or country-dependent information such as date, time,currency, etc., should be removed from program code.

2.8.4.1 Date, time

Code your date and time locale independently, using Symbian OS formattingfunctions TTime::FormatL() to format a date or time. This can be done tohonor locale-specific settings within TLocale that include the order of day,month, and year within a short date. Use formatting strings in followingformat "%/0%1%/1%2%/2%3%/3 " instead of "%M%D%Y".

Standard date, time, and duration formatting strings can be found fromAVKON resources. It is recommended that AVKON formatting strings beused.

This example shows how to produce a short date of 10/20/99 (M/D/Y) localeindependently by using formatting strings from AVKON resources.

Version 1.0 | May 5, 2004

Page 33: Symbian OS Coding Conventions v1 0 En

8/4/2019 Symbian OS Coding Conventions v1 0 En

http://slidepdf.com/reader/full/symbian-os-coding-conventions-v1-0-en 33/58

Symbian OS: Coding Conventions in C++ | 33

#include <avkon.rsg>TTime homeTime;homeTime.HomeTime(); // get home timeHBufC* dateFormatString = iEikonEnv->AllocReadResourceLC

(R_QTN_DATE_SHORT_WITH_ZERO); // Read format string from AVKON resource

TBuf<32> buf;homeTime.FormatL(buf,*dateFormatString); // Format the date

CleanupStack::PopAndDestroy(); // dateFormatString

Available formatting strings in AVKON resources.

Resource name Examples of Formatted Output

R_QTN_DATE_SHORT 1.9.00

R_QTN_DATE_SHORT_WITH_ZERO 01.09.00

R_QTN_DATE_USUAL 1.9.2000

R_QTN_DATE_USUAL_WITH_ZERO 01.09.2000

R_QTN_DATE_WITHOUT_YEAR 1.9.

R_QTN_DATE_WITHOUT_YEAR_WITH_ZERO 01.09.

R_QTN_TIME_USUAL 13:15, 3:15

R_QTN_TIME_USUAL_WITH_ZERO 03:15

R_QTN_TIME_LONG 13:15:15, 3:15:15

R_QTN_TIME_LONG_WITH_ZERO 03:15:15

R_QTN_TIME_DURAT_SHORT 13:15, 3:15

R_QTN_TIME_DURAT_SHORT_WITH_ZERO 03:15

R_QTN_TIME_DURAT_LONG 13:55:23, 3:15:12

R_QTN_TIME_DURAT_LONG_WITH_ZERO 03:15:12

R_QTN_TIME_DURAT_MIN_SEC 13:15, 3:05

R_QTN_TIME_DURAT_MIN_SEC_WITH_ZERO 13:15, 03:05

Table 2: Available formatting strings in AVKON resources

Make sure that the long date format is not defined by the short date format.The two should not be interdependent.

Example: 

In Swedish, the standardized short date format is YMD (1999-09-22) but thelong date format is DMY (den 22 september 1999). If the format for longdates is dependent on the short date format, the long date will appear as"1999 september den 22," which is incorrect.

Version 1.0 | May 5, 2004

Page 34: Symbian OS Coding Conventions v1 0 En

8/4/2019 Symbian OS Coding Conventions v1 0 En

http://slidepdf.com/reader/full/symbian-os-coding-conventions-v1-0-en 34/58

Symbian OS: Coding Conventions in C++ | 34

2.8.4.2 Currency value

Never assume the location of a currency symbol with reference to the number,number of characters for the currency symbol, and how the negative currency isformatted.

Example: 

In the United States, it is $5

In France, it is 5 €

Use TCurrencySymbol::Set() to get the currency symbol and the formattingfunctions in TLocale to format a currency value.

2.8.4.3 Collation

Collation should only be applied to whole strings; in general, collation should use

the CompareC() descriptor function and not pattern-matching functions basedon single characters.

Symbian OS supports multiple collation methods within a locale, each of whichhas a unique identifier. Many locales will have customized standard collationmethods, and applications should not rely on collation methods being the sameacross all locales. The static function Mem::CollationMethods()can be usedto get the number of collation methods supported by the current locale. Inaddition, within a collation method, Symbian OS supports collation levels, whichcan be used to specify the degree of matching required.

2.8.4.4 Decimal separators

Never assume what character is used for decimal separator. UseTLocale::DecimalSeparator() to get the locale-dependent decimalseparator.

2.8.5 Fonts

Never hard code a font name. Use a resource file and then reference the fontname by its logical name in the code. There is a possibility that a font namemay also require localization.

Example of bad coding practice:

CAgnAppEnv::CAgnAppEnv(CAgnAppUi* aApp, CEikonEnv* aEikEnv )

: iApp(aApp), iTheEikonEnv(aEikEnv),iNormalTextFormat(_L("Arial"),180),iBoldTextFormat(_L("Arial"),150),iBoldUnderlineTextFormat(_L("Arial"),150),iEntryCodeFormat(_L("Arial"),150),iSymbolFormat(_L("Symbol"),150),iTextCursorFormat(_L("Arial"),150){__DECLARE_NAME(_S("CAgnAppEnv"));}

Version 1.0 | May 5, 2004

Page 35: Symbian OS Coding Conventions v1 0 En

8/4/2019 Symbian OS Coding Conventions v1 0 En

http://slidepdf.com/reader/full/symbian-os-coding-conventions-v1-0-en 35/58

Symbian OS: Coding Conventions in C++ | 35

Example of good coding practice:

void CCalcMemoryDialog::DoCalculateColumnWidths(){TBuf<KFontNameSize> listboxFontName;iCoeEnv->ReadResource(listboxFontName, QTN_CALC_LISTBOX_FONT_NAME);

TFontSpec spec(listboxFontName, KFontNameSize);iFont=iEikonEnv->CreateScreenFontL(spec);...}

Asian fonts often have to be taller than Latin ones as the minimum size inpixels that can be used is greater. This may affect assumptions about thenumber of lines allowed in a dialog or menu.

Version 1.0 | May 5, 2004

Page 36: Symbian OS Coding Conventions v1 0 En

8/4/2019 Symbian OS Coding Conventions v1 0 En

http://slidepdf.com/reader/full/symbian-os-coding-conventions-v1-0-en 36/58

Symbian OS: Coding Conventions in C++ | 36

3 . C o d i n g I d i o m s

This section contains a review of the techniques that Symbian OS provides for 

preventing memory-related problems. All developers should have a clear understandingof them — they are the crux of Symbian OS programming!

3.1 General Principle

Do NOT put strings to be localized into code files. Use logical names in codefiles and put the actual strings in a separate resource header file (.loc), i.e.,not to the same header file as resource structures.

Build code that gives zero compiler warnings and zero link errors; it isdangerous to ignore compiler warnings, and these are highly likely togenerate errors on other compilers. Complacency regarding compiler 

warnings may lead to a situation where important new compiler warnings arenot noticed among a pile of familiar warnings.

Strive to write tight and efficient code.

Minimize the stack use.

Minimize the number of calls to the allocator.

Always ask the question, what would happen if this code were to leave?

Avoid hard-coding magic numbers; use constants or enumerations.

3.1.1 Basic types

e32def.h defines concrete types; use them

TInt32 integer;

and not

long int integer;

3.1.2 String and buffer classes

Use the Symbian OS descriptor classes, such as TPtr, TDesC, and TBuf<n>,instead of native text string classes or handcrafted buffer classes. These result in

code that is much more easily converted between wide-character and narrow-character builds, and also has gains in efficiency and robustness over other string classes. For the details of the class usage, please refer to SDK help for more details.

3.1.3 Date classes

Use the Symbian OS date and time classes, such as TDateTime, instead of handcrafted alternatives.

Version 1.0 | May 5, 2004

Page 37: Symbian OS Coding Conventions v1 0 En

8/4/2019 Symbian OS Coding Conventions v1 0 En

http://slidepdf.com/reader/full/symbian-os-coding-conventions-v1-0-en 37/58

Symbian OS: Coding Conventions in C++ | 37

3.1.4 Class types

It is strongly recommended that you use direct initialization for class types.

The use of copy initialization is deprecated.

Explanation: If you declare a class type using the copy constructor = like this:

TParsePtrC parser=TPtrC(FileName);

then the initialization of TParsePtrC effectively requires a call toTParsePtrC::TParsePtrC(const TPtrC&) followed by a call toTParsePtrC's copy constructor TParsePtrC::TParsePtrC(constTParsePtrC&).

This is significantly more expensive than directly initializing the class type, whichis done like this:

TParsePtrC parser((TPtrC(FileName)));

and eliminates the redundant call of the copy constructor.

Note that you need the extra set of brackets around (TPtrC(FileName)) inorder to allow the compiler to recognize that you are instantiating an object of type TParsePtrC and not declaring a function that returns something of typeTParsePtrC. Without the brackets the code is ambiguous.

3.1.5 Protect objects

Catch programming and run-time errors early by using pre- and post-conditionsin functions i.e., assert that those conditions required for correct execution holdtrue. Two mechanisms support this programming style:

__ASSERT_ALWAYS / __ASSERT_DEBUG class invariants.

Both of these mechanisms must be used. They catch programming errors earlyand aid in communicating the design and purpose of the class.

3.1.5.1 Assertions

__ASSERT_ALWAYS to catch run-time invalid input.

__ASSERT_DEBUG to catch programming errors.

3.1.5.2 Class invariants

Define class invariants for nontrivial classes using:

__DECLARE_TEST to specify the allowed stable states for that class.

Call the invariant at the start of all public methods (where feasible) using:

__TEST_INVARIANT  to ensure the object is in a stable state prior toexecuting the function.

Calls are compiled out in release software builds.

Version 1.0 | May 5, 2004

Page 38: Symbian OS Coding Conventions v1 0 En

8/4/2019 Symbian OS Coding Conventions v1 0 En

http://slidepdf.com/reader/full/symbian-os-coding-conventions-v1-0-en 38/58

Symbian OS: Coding Conventions in C++ | 38

For non-const methods call the invariant at the end of the method. This ensuresthat the object has been left in a stable state after executing the method:

// Removes text content, commencing at position aPos, over aLength// number of charactersvoid CComplexTextObject::Delete(TInt aPos,TInt aLength)

{__TEST_INVARIANT;__ASSERT_ALWAYS(aPos>0,Panic(EPosOutsideTextObject));iTextBuffer->Delete(aPos,aLength);__TEST_INVARIANT;}

3.1.5.3 Private inheritance

Avoid private inheritance: use composition instead. Inheritance should berestricted to cases when the relationship really is "a kind of".

3.1.5.4 Multiple inheritance

Multiple inheritance is fine; only M classes (mix-ins) are inherited.

Mix-ins specify interface only, not implementation.

Inherit from CBase-derived class first; achieve correct layout of the v-table.

Inherit from only one CBase-derived class; other superclasses must be mix-ins.

Refer to the Symbian Developer Library for further information.

Refer to Section 2.7.5, “Multi-inheritance. ”

class CGlobalText : public CPlainText, public MLayDoc, public MformatText{…};

3.2 Exception Handling in Symbian OS C++

3.2.1 Check for out-of-resource errors

Memory is always a scarce resource in handheld devices. As more applicationsare launched and more resources are allocated in the device, eventually all of the resources will be used up. In any application, an error may occur at run time

due to a lack of resources, for example, the machine may run out of memory, or a communication port may be unavailable. This type of error is known as anexception.

An exception should be distinguished from a programming error: A programmingerror can be addressed by fixing the program, but it is impossible to make aprogram free from the possibility of an exception occurring.

Therefore, programs should be able to recover from exceptions when they occur.This is particularly important in Symbian OS, for the following reasons:  Symbian OS applications are designed to run for long periods (months or 

even years) without interruption or system reboot. 

Version 1.0 | May 5, 2004

Page 39: Symbian OS Coding Conventions v1 0 En

8/4/2019 Symbian OS Coding Conventions v1 0 En

http://slidepdf.com/reader/full/symbian-os-coding-conventions-v1-0-en 39/58

Symbian OS: Coding Conventions in C++ | 39

Symbian OS applications are designed to run on machines that have limitedresources, particularly memory. Therefore, an out-of-resource error is morelikely to occur than in a desktop application. 

Not all Symbian OS-based devices will have the same resources i.e., an

application designed and verified on one type of Symbian OS-based devicemight run into resource exceptions on another Symbian OS-based device fromanother manufacturer. 3.2.2 Conventional error-checking methods

In a conventional C or C++ program, an if statement might typically be used tocheck for an out-of-resource error. For example:

if ( (myObject = new CSomeObject()) == NULL ){

PerformSomeErrorCode();}

3.2.3 Problems with conventional methods

There are two problems with this conventional approach:

It requires many extra lines of code to put such error checking around everysingle function that might cause an out-of-resource error. This increasescode size and reduces readability.

If a constructor fails to allocate resources, there is no way to return an error code, because constructors have no return value. The result would be anincompletely allocated object, which could cause a program crash.

C++ exception handling (try, catch, and throw) provides solutions to theseproblems, but is not used in Symbian OS because:

Compiler support for C++ exception handling was unavailable or inadequateat the time Symbian OS was designed.

Symbian OS exception handling is specialized for use with other SymbianOS conventions (C and T classes, 32-bit integer error codes), allowing lower overheads than for C++ exception support.

Existing C++ programs for other platforms that use exception handling must bemodified before they can be used.

Symbian OS provides its own system of exception handling. The basic operating

system support for exceptions comes from: The TRAP macro and its variant, TRAPD, which allow code to be run under a

trap harness.

The User::Leave() call, which terminates the current function, and returnsto the trap harness, specifying an error code.

These are analogous to C++’s exception-handling support (try/catch andthrow).

Version 1.0 | May 5, 2004

Page 40: Symbian OS Coding Conventions v1 0 En

8/4/2019 Symbian OS Coding Conventions v1 0 En

http://slidepdf.com/reader/full/symbian-os-coding-conventions-v1-0-en 40/58

Symbian OS: Coding Conventions in C++ | 40

3.3 Solutions in Symbian OS

Symbian OS applications can achieve efficient exception handling by following theserules:

Rule 1: All functions that can leave should have a letter L at the end of their names. Leaves propagate back up through the call stack, via "leavefunctions" until they are caught by a trap harness. This is normallyimplemented in the E32Main() main function for console-based applications,or is provided as part of the application framework for GUI programs.

Rule 2: When allocating memory on the heap, if the pointer to the memory isan automatic variable (i.e., not a member variable), it should be pushed ontothe cleanup stack so that it can be deleted when a leave occurs. All objectspushed onto the cleanup stack should be popped off it before they aredestroyed.

Rule 3: A C++ constructor or destructor must not leave or fail. Therefore, if 

construction of an object can fail with an out-of-resource error, all theinstructions that might fail should be taken out of the C++ constructor and putinto a ConstructL() function, which should be called after the C++constructor has completed. This is called two-phase construction.

3.3.1 Rule 1: Functions that leave, and trap harnesses

3.3.1.1 Functions that leave

Instead of returning an error code, functions in Symbian OS should leavewhenever an out-of-resource error occurs. A leave is a call to User::Leave(),  and it causes program execution to return immediately to the trap harness within

which the function was executed. All functions that can leave should have the suffix L. This enables programmersto know that the function might leave. For example:

void MyFunctionL(){iMember = new (ELeave) CMember;iValue = AnotherFunctionL();User::LeaveIfError(iSession.Connect());}

Each line in MyFunctionL could cause a leave. Any of these lines makesMyFunctionL a leaving function.

Note, however, that it is very rarely necessary for application code to use aTRAP, since the application framework provides traps in the right places, andcode to handle them. Traps should not be used in normal coding. In general, theway to deal with leaves is to simply allow them to propagate through the functionby adding a letter L suffix to the function name.

3.3.1.2 The new (ELeave) operator 

The possibility of the new operator failing arises so often in Symbian OS that thenew operator has been overridden to take a parameter, ELeave. When calledwith this parameter, the overridden new operator will leave if it fails to allocatethe required memory. ELeave is defined as follows in e32std.h:

enum TLeave {ELeave};

Version 1.0 | May 5, 2004

Page 41: Symbian OS Coding Conventions v1 0 En

8/4/2019 Symbian OS Coding Conventions v1 0 En

http://slidepdf.com/reader/full/symbian-os-coding-conventions-v1-0-en 41/58

Symbian OS: Coding Conventions in C++ | 41

This is implemented globally, so any class can use the new (ELeave) version of the operator. For example:

CSomeObject* myObject = new CSomeObject;if ( !myObject ) User::Leave(KErrNoMemory);// Can be replaced in by:CSomeObject* myObject = new (ELeave) CSomeObject;

3.3.1.3 The NewL() and NewLC() conventions

By convention, Symbian OS classes often implement the methods NewL()andNewLC(). These are declared as static methods in the class definition, whichallows them to be called before an instance of the class exists. They are invokedusing the class scope. For example:

CSomeObject* myObject = CSomeObject::NewL();

NewL() creates a new instance of the class on the heap and leaves if an out-of-memory error occurs. For simple objects this simply involves a call to new(ELeave). However, for compound objects it can incorporate two-phaseconstruction (see Rule 3, below).

NewLC() creates a new instance of the class on the heap and pushes it onto thecleanup stack (see Rule 2, below), leaving if an out-of-memory error occurs. (Ingeneral, the C suffix at the end of a method means that it pushes a createdobject onto the heap before returning.)

When creating C-class objects, programs should use NewL() if a member variable will point to the object, and NewLC() if an automatic variable will point toit. However, it is not always advisable to implement NewL() and NewLC() for every class. If NewL() or NewLC() are called from only one place in theapplication, implementing them will actually use more lines of code than it saves.

It is a good idea to assess the need for NewL() and NewLC() for each individualclass.

3.3.1.4 Using a trap harness: TRAP and TRAPD

In exceptional circumstances, a developer is permitted to handle a leave byusing a trap harness. However, the use of TRAP and TRAPD is only for specialsituations; for all general coding they should not be used. Usually the bestcourse of action is to allow the leave to propagate back to the Active Scheduler for default handling. If there is any doubt about whether a trap harness is reallyneeded, there is probably a cheaper or cleaner way to achieve the samefunctionality.

Symbian OS provides two trap harness macros, TRAP and TRAPD, which are bothvery similar. Whenever a leave occurs within code executed inside the harness,program control returns immediately to the trap harness macro. The macro thenreturns an error code, which can be used by the calling function.

To execute a function within a trap harness, use TRAPD as follows:

TRAPD( error, doExampleL() );if ( error != KerrNone )

{// Do some error code}

Version 1.0 | May 5, 2004

Page 42: Symbian OS Coding Conventions v1 0 En

8/4/2019 Symbian OS Coding Conventions v1 0 En

http://slidepdf.com/reader/full/symbian-os-coding-conventions-v1-0-en 42/58

Symbian OS: Coding Conventions in C++ | 42

TRAP differs from TRAPD only in that the program code must declare the leavecode variable. TRAPD is more convenient to use, as error is declared inside themacro. Using TRAP, the above example would become:

TInt error;

TRAP( error, doExampleL() );if ( error != KerrNone ){// Do some error code}

Any functions called by doExampleL() are also executed within the trapharness, as are any functions called by them, and so on. A leave occurring inany function nested within doExampleL() will return to this trap harness. Other TRAP harnesses can also be nested within the first, so that errors are checkedat different levels within the application.

3.3.2 Rule 2: Using the cleanup stack

3.3.2.1 Why the cleanup stack is needed 

If a function leaves, control returns immediately to the TRAP harness within whichit was called, generally the default TRAP harness inside the thread’s ActiveScheduler. This means that any automatic variables within functions called insidethe TRAP harness are destroyed. However, a problem arises if any of theseautomatic variables are pointers to objects allocated on the heap. When theleave occurs and the pointer is destroyed, the object it pointed to is orphanedand a memory leak occurs.

Example:

void doExampleL()

{CSomeObject* myObject1 = new (ELeave) CSomeObject;CSomeObject* myObject2 = new (ELeave) CSomeObject;// WRONG}

In this example, if  myObject1 was created successfully, but there wasinsufficient memory to allocate myObject2, myObject1would be orphaned onthe heap.

Thus, you need some mechanism for retaining any such pointers, so that thememory they point to can be freed after a leave. Symbian OS provides amechanism for this in the cleanup stack.

3.3.2.2 Using the cleanup stack 

The cleanup stack is a stack containing pointers to all the objects that need to befreed when a leave occurs. This means all C-class objects pointed to byautomatic variables rather than instance data.

When a leave occurs, the TRAP or TRAPD macro pops and destroys everything onthe cleanup stack that was pushed onto it since the beginning of the TRAP.

All applications have their own cleanup stack, which they must create. (Theapplication framework automatically creates one in GUI applications.) Typically,all programs will have at least one object to push onto the cleanup stack.

Objects are pushed onto the cleanup stack using CleanupStack::PushL()and

popped from it using CleanupStack::Pop() . Objects on the cleanup stackshould be popped when there is no longer a chance that they could be orphaned

Version 1.0 | May 5, 2004

Page 43: Symbian OS Coding Conventions v1 0 En

8/4/2019 Symbian OS Coding Conventions v1 0 En

http://slidepdf.com/reader/full/symbian-os-coding-conventions-v1-0-en 43/58

Symbian OS: Coding Conventions in C++ | 43

by a leave, which is usually just before they are deleted. PopAndDestroy() isnormally used instead of Pop(), as this ensures the object is deleted as soon asit is popped, avoiding the possibility that a leave might occur before it has beendeleted, causing a memory leak.

A compound object that owns pointers to other C-class objects should deletethose objects in its destructor. Therefore any object that is pointed to by member data of another object (rather than by an automatic variable) does not need to bepushed onto the cleanup stack. In fact, it must not be pushed onto the cleanupstack, or it will be destroyed twice if a leave occurs: once by the destructor, andonce by the TRAP macro.

3.3.2.3 Guideline for using cleanup stack 

Where appropriate, use it in preference to TRAP harnesses as it is quicker and more efficient.

Use the checking methods of CleanupStack::Pop to check that the PushL 

and Pop are balanced if possible.

Use CleanupStack::PopAndDestroy if you are finished using the object.

Standard usage:

For CBase'd heap-created objects, push and pop the pointer to the object, for example:

CObject* object = CObject::NewL();CleanupStack::PushL(object);object->LeavingFunctionL();CleanupStack::PopAndDestroy(object);

RClasses

For RClass objects that define a Close() method, use CleanupClosePushL  where applicable:

RObject object;object.Open();CleanupClosePushL(object);object.LeavingFunctionL();CleanupStack::PopAndDestroy(&object); 

This may not be suitable for all RClass objects. For instance it may not besuitable for RPointerArray if you have already added objects to the array.Calling Close() in that instance could orphan the added objects unless they are

also on the cleanup stack.

If you wanted to call nonleaving functions after LeavingFunctionL , then it ispreferable to leave the object on the cleanup stack rather than callingCleanupStack::Pop() and then the nonleaving function, as it results in lesscode.

Version 1.0 | May 5, 2004

Page 44: Symbian OS Coding Conventions v1 0 En

8/4/2019 Symbian OS Coding Conventions v1 0 En

http://slidepdf.com/reader/full/symbian-os-coding-conventions-v1-0-en 44/58

Symbian OS: Coding Conventions in C++ | 44

TcleanupItems

Some classes or methods will require more complicated cleanup. Use aTCleanupItem and provide a function to call that does the required cleanup.Declare these functions as either local functions or static class functions: // Allows correct cleanup of specified objects by using the// cleanup stack instead of a trap harness.void RObject::ReleaseOnCleanup(TAny* aObject){reinterpret_cast(aObject)->Release();}

// may increase share on a reference counted objectRObject*object = GetObject();CleanupStack::PushL(TCleanupItem(ReleaseOnCleanup,object));iContainer->AddL(object);CleanupStack::Pop(object); // Pop the TCleanupItem::iPtr

Heap allocated arrays

Use CleanupArrayDeletePushL() when pushing an array of objects onto thecleanup stack. This ensures that PopAndDestroy()will call delete[] to deletethe array correctly.

TObject objectArray = new(ELeave) TObject[numberOfElements];CleanupArrayDeletePushL(objectArray);…CleanupStack::Pop(objectArray);

3.3.3 Rule 3: Two-phase construction

Sometimes a constructor will need to allocate resources, such as memory. Themost ubiquitous case is that of a compound C-class: If a compound classcontains a pointer to another C-class, it will need to allocate memory for thatclass during its own construction.

Note: C-classes in Symbian OS are always allocated on the heap, and alwayshave CBase as their ultimate base class.

In the following example, CMyCompoundClass has a data member that is apointer to a CMySimpleClass.

Here’s the definition for CMySimpleClass :

class CMySimpleClass : public CBase{public:

CMySimpleClass();~CMySimpleClass();…

private:TIntiSomeData;

};

Version 1.0 | May 5, 2004

Page 45: Symbian OS Coding Conventions v1 0 En

8/4/2019 Symbian OS Coding Conventions v1 0 En

http://slidepdf.com/reader/full/symbian-os-coding-conventions-v1-0-en 45/58

Symbian OS: Coding Conventions in C++ | 45

Here’s the definition for CMyCompoundClass:

class CMyCompoundClass : public CBase{public:

CMyCompoundClass();

~CMyCompoundClass();…

private:CMySimpleClass* iSimpleClass; // owns another C-class

};

Consider what a developer might be tempted to write as the constructor for CMyCompoundClass :

CMyCompoundClass::CMyCompoundClass(){iSimpleClass = new CMySimpleClass; // WRONG}

Now consider what happens when a new CMyCompoundClass is created:

CMyCompoundClass* myCompoundClass = new (ELeave) CMyCompoundClass;

With the above constructor, the following sequence of events occurs:

1. Memory is allocated for the instance of CMyCompoundClass. 

2. The constructor of CMyCompoundClass is called. 

3. The constructor creates a new instance of CMySimpleClass and stores apointer to it in iSimpleClass.

4. The constructor completes.

But, if stage 3 fails due to insufficient memory, what happens? There is no wayto return an error code from the constructor to indicate that the construction wasnot completed. The new operator will return a pointer to the memory that wasallocated for the CMyCompoundClass , but it will point to a partially constructedobject.

If we make the constructor leave, we can detect when the object was not fullyconstructed, as follows:

CMyCompoundClass::CMyCompoundClass() // WRONG{iSimpleClass = new (ELeave) CMySimpleClass;}

However, this is not a viable method for indicating that an error has occurred,because we have already allocated memory for the instance of CMyCompoundClass . A leave would destroy the pointer to the allocated memory(this), and there would be no way to free it, resulting in a memory leak.

The solution is to allocate all of the memory for the components of the object,after the C++ constructor has initialized the compound object. In Symbian OSthis is performed in a ConstructL() method by convention. For example:

void CMyCompoundClass::ConstructL() // RIGHT{iSimpleClass = new (ELeave) CMySimpleClass;}

Version 1.0 | May 5, 2004

Page 46: Symbian OS Coding Conventions v1 0 En

8/4/2019 Symbian OS Coding Conventions v1 0 En

http://slidepdf.com/reader/full/symbian-os-coding-conventions-v1-0-en 46/58

Symbian OS: Coding Conventions in C++ | 46

The C++ constructor should contain only initialization code that cannot leave (if any):

CMyCompoundClass::CMyCompoundClass() // RIGHT{// Initialization that cannot leave.}

The object is now constructed as follows:

CMyCompoundClass* myCompoundClass = new (ELeave) CMyCompoundClass;CleanupStack::PushL(myCompoundClass);

  myCompoundClass->ConstructL(); // RIGHT

This can be encapsulated in a NewL() or NewLC() method for convenience.

3.3.3.1 Implementing two-phase construction using NewL() / NewLC()

If a compound object has a NewL() method (or NewLC()), then this should

contain both stages of construction. After the allocation stage, the object shouldbe pushed onto the cleanup stack before ConstructL() is called, in caseConstructL() leaves. For example:

CMyCompoundClass* CMyCompoundClass::NewLC(){CMyCompoundClass* self = new (ELeave) CMyCompoundClass;CleanupStack::PushL(self);self->ConstructL();return self;}

CMyCompoundClass* CMyCompoundClass::NewL(){CMyCompoundClass* self = new (ELeave) CMyCompoundClass;CleanupStack::PushL(self);

self->ConstructL();CleanupStack::Pop(); // selfreturn self;}

3.4 Common Mistakes

3.4.1 Misuse of TRAP and TRAPD

Some classes repeatedly include code of the form:

void NonLeavingFunction(){TRAPD(error, LeavingFunctionL());}

While this is legitimate code, it should not be widely used. A trap harness isexpensive in terms of executable binary size and execution speed, and unlessused very carefully can lead to errors being lost. Often a trap is used where itwould simply be better to add a letter L to the end of the method name and allowthe leave to propagate up. Note, however, that to maintain library compatibility,this may not always be possible. Library design should always take account of future leave needs.

Version 1.0 | May 5, 2004

Page 47: Symbian OS Coding Conventions v1 0 En

8/4/2019 Symbian OS Coding Conventions v1 0 En

http://slidepdf.com/reader/full/symbian-os-coding-conventions-v1-0-en 47/58

Symbian OS: Coding Conventions in C++ | 47

The following code is particularly bad, as the whole TRAP is meaningless!

void NonLeavingFunction(){TRAPD(error, LeavingFunctionL());if ( error != KErrNone )

User::Leave( error );}

3.4.2 Misuse of the new operator 

This code is illegal and dangerous:

void NonLeavingFunction(){bar* foo = NULL;TRAPD(error, foo = new bar());foo->DoSomething();}

In this situation it is essential to use the new (ELeave) version of the operator,as new on its own will not leave. This could lead to both memory leaks and useof an uninitialized pointer.

3.4.3 Misuse of the L suffix

void NonLeavingFunction(){LeavingFunctionL();

bar* foo = new (ELeave) bar();bar* foo1 = bar::NewL();}

All three lines of this function break the L suffix rule. There are two options here:

1. The leaving lines must be caught in a TRAP (probably not the right solution).

2. The NonLeavingFunction should become an L function (probably better).

Note that this code also breaks Rule 2 (Using the cleanup stack, above),because if NewL leaves, foo will become orphaned on the heap.

3.4.4 Memory leaks

It is very important to carry out memory testing regularly during the developmentof Symbian OS code. If a memory leak is discovered, it is much easier to locate itwithin the context of the work that is being currently undertaken, rather than

having to search through the whole application.

Symbian OS provides heap failure tools for debug builds, which can be used toassist in the stress testing of memory in Symbian OS code. In doing this, you arelooking for two aspects of the application’s behavior:   Behavior of the application when memory runs out.

Memory leakage, reported when the application is closed.

It is particularly important to actually close the application using the Back softkey when memory testing. Closing the emulator directly using the top-right closebutton will not allow the memory checking code to run.

Version 1.0 | May 5, 2004

Page 48: Symbian OS Coding Conventions v1 0 En

8/4/2019 Symbian OS Coding Conventions v1 0 En

http://slidepdf.com/reader/full/symbian-os-coding-conventions-v1-0-en 48/58

Symbian OS: Coding Conventions in C++ | 48

3.4.5 Using tools in the WINS/WINSCW emulator 

The WINS/WINSCW emulator provides a tool for checking memory behavior bypressing CTRL-SHIFT-ALT-P . Details are presented in the SDK documentationand also in the Professional Symbian Programming book, on page 158. The

utility described in the book is available in most SDKs that are based on SymbianOS, such as the Series 60 SDK. The outlook of the testing utility screen isdifferent from one SDK to another:

Figure 1: The Series 60 terminal emulator memory stress testing utility

Figure 2: The Nokia 9210 Communicator emulator memory stress testingutility

Debugging a memory leak in Symbian OS can be daunting, but there aretechniques that make the process fairly painless. However, memory leaks are

never trivial to find, and prevention is the best cure! The following tips willprevent leaks appearing in the first place, and ease the pain of searching themout later:

Understand the cleanup stack and the Leave/TRAP paradigm.

Build and run code regularly — if a leak appears, it will be more obviouswhere it was caused.

Use Symbian OS v6.x/v7.0s heap-checking macros.

When testing, exit the application. Don’t just kill the emulator.

Code reviews are very useful.

There are two types of memory leak. A static leak is a repeatable leak thatalways occurs when the application is run; it is caused by mismatched new and

Version 1.0 | May 5, 2004

Page 49: Symbian OS Coding Conventions v1 0 En

8/4/2019 Symbian OS Coding Conventions v1 0 En

http://slidepdf.com/reader/full/symbian-os-coding-conventions-v1-0-en 49/58

Symbian OS: Coding Conventions in C++ | 49

delete operators. These are relatively easy to find because they always happenin the same place and thus can be debugged. A dynamic leak is one that isnontrivial to repeat, for example a leak caused by an error condition, or racecondition. This is trickier to find, as not all paths through the code will cause it.

3.4.5.1 What leaked? 

When an application is closed, the emulator will panic if memory has leaked (thisis actually a _UHEAP_MARKEND macro running). An application should always exitcleanly, even in development. If a "panic on close" appears while developing, itcan be fixed straight away. If it is left, it will be 10 times more difficult to trackdown later.

Under the Microsoft Visual C++ debugger, the panic appears as a "User Breakpoint called from code at location 0xxxxxx" dialog. The stack trace (useView>Debug Windows>Call Stack) shows that it is in the destructor of CCoeEnv.

To continue, press OK and F5. Another User Breakpoint will be reached, this

time at DebugThreadPanic. The output window now shows Panic ALLOC andan address. Select this address and copy it to the clipboard (Edit>Copy).

This is the hexadecimal address of the memory cell that has not beendeallocated. From this address, it is possible to find out the type of the leakedclass by attempting to cast the address to a few possible types. Use the "Quickwatch" window in Visual Studio, and try to cast the pointer badCell to thefollowing types:

CBase* (in case it is a CBase-derived object).

TDesC16* (in case it is a string).

If neither of these casts gives any useful information, it could be an R-Class(resource handle), although the server should normally panic if a client is notclosed. Alternatively it could be a T-Class that is mistakenly on the heap. Notethat this technique could give slightly skewed information if a large compound C-Class has leaked, as it is likely that one of the members of the large class will bereported, rather than the parent class itself.

3.4.5.2 Where was it allocated? 

Once the address of the leaked memory is known, its allocation point can befound by setting a conditional breakpoint in the heap allocator function.

All heap memory allocation goes through the function RHeap::Alloc(int), so

start by putting a breakpoint there. Symbian does not currently supply the sourcecode for this function, but a breakpoint can be set explicitly using the Edit>Breakpoints>Break At feature of Microsoft Visual C++.

Use Debug>Go (F5) to continue until the system's first allocation. The sourcecode is not viewable, but the disassembled code can be seen. Scroll downthrough the disassembled code, passing the label retryAllocation, until theline before the start of the next function, roundToPageSize. Put a breakpoint onthe RET line before it, at which point, the register EAX will contain the return valuefrom the RHeap::Alloc function. Use Edit>Breakpoints to set up a breakpointwhen the value is equal to the offending cell. First, disable the breakpoint atRHeap::Alloc, select the new breakpoint, and use Condition to set thecondition that the return value is the cell being tracked.

Version 1.0 | May 5, 2004

Page 50: Symbian OS Coding Conventions v1 0 En

8/4/2019 Symbian OS Coding Conventions v1 0 En

http://slidepdf.com/reader/full/symbian-os-coding-conventions-v1-0-en 50/58

Symbian OS: Coding Conventions in C++ | 50

Click OK to both dialogs, and then use Debug>Go to continue. Run theapplication as before. When execution stops at the breakpoint, examine thestack to see where the offending cell was allocated.

Sometimes the same cell may be allocated and deallocated a few times. Only the

final allocation is of interest.

If the cell doesn't get allocated, it may be because this run was a bit differentfrom the first one, and the leaking cell was at a different location. Continue untilapplication exit, and find a new offending cell address. Then set that as anadditional breakpoint at the same location as the other but with a condition tocatch the new offending cell, and use Debug>Restart to restart. The error message "Cannot restore all the breakpoints" may occur. This is because theEUSER DLL isn't loaded when the emulator executable (EPOC.EXE) first starts.The solution is to re-enable the RHeap::Alloc(int) breakpoint, run until that iscalled, and then restore the other, conditional, breakpoints.

Note that code slows down a lot with this breakpoint in place, so enable it at the

last moment! Also, the same address may be allocated many times — which oneis the leak? This involves investigating the call stack each time the breakpoint ishit to find the context!

3.5 Asserts and Panics

Using __ASSERT_DEBUG test macros can prevent many problems. They should be usedliberally to check for silly parameters coming into functions, null pointers, and other error conditions. Many error conditions will not trip up the application straight away, but willlead to side effects later. If errors are caught as soon as they occur, debugging becomesmuch easier later. For example:

CMyClass::Function(CThing* aThing){__ASSERT_DEBUG(aThing, Panic(EMyAppNullPointerInFunction));}

Version 1.0 | May 5, 2004

Page 51: Symbian OS Coding Conventions v1 0 En

8/4/2019 Symbian OS Coding Conventions v1 0 En

http://slidepdf.com/reader/full/symbian-os-coding-conventions-v1-0-en 51/58

Symbian OS: Coding Conventions in C++ | 51

4 . S ys te m R e s o u rc e U s a g e (R O M a n d R A M )

4.1 Importance

A phone is a resource-limited device. However, there is a great deal of functionalityavailable, and this places great demands on the available system resources. Developersneed to be aware of these constraints, and attempt to use as few as possible of theselimited resources. 4.2 Reducing Code Size

It is important that final compiled code be as small as possible, to maximize the availablespace on the device. The following tips will provide guidance on how to ensure that nospace is wasted. Take time to check code for these issues, and think about other waysin which the compiled size could be reduced.

4.2.1 Unnecessary exported functions

When functions are exported using IMPORT_C and EXPORT_C from a DLL, theyuse up space for the export table. Only functions that need to be used outside of the DLL should be exported.

4.2.2 Copy and paste

Copy and paste often leads to code bloat. When reusing code from other modules, ask the following questions: 

1. Is this code actually needed?

2. Is too much code being copied for the task?

3. Would it be better to abstract the function into a base class or helper moduleso it can be used from more than one place, rather than copy it?

4. Could the code be rewritten more efficiently for the required task, rather thancopying something that is "close" to what is required?

4.2.3 Obviously decomposable functions

There are many places where a number of functions that perform very similar tasks are present in a class. Often this common code can be abstracted out intoa single function, which is parameterized to perform the different tasks required.A common example of this kind of thing is a class that implements both NewL and NewLC. Rather than duplicate the code in both functions, NewL can just callNewLC, performing a CleanupStack::Pop afterwards.

4.2.4 Excessive TRAP harnesses

Trap harnesses use up space when they are compiled. Code that contains manyTRAP macros (e.g., more than five in a class) is using up too much space. It isalso probably incorrectly designed, as the TRAP harness is not intended for useextensively in normal code. It is there to allow advanced development of special

error handling and recovery routines.

Version 1.0 | May 5, 2004

Page 52: Symbian OS Coding Conventions v1 0 En

8/4/2019 Symbian OS Coding Conventions v1 0 En

http://slidepdf.com/reader/full/symbian-os-coding-conventions-v1-0-en 52/58

Symbian OS: Coding Conventions in C++ | 52

4.2.5 Debug code in release

If there is any code for logging, debugging, or testing, it needs to be excluded inrelease builds. The compiler directive #ifdef _DEBUG can be used for thispurpose.

4.2.6 Unnecessary virtual functions

Unnecessary virtual functions are bad, for reasons similar to exports, as theycreate extra vtable functions.

4.2.7 Use common controls

If possible, use framework controls that are available in the system (or other shared DLLs) instead of developing new ones.

4.2.8 Misuse of the _L macro

The _L literal macro is now deprecated and replaced by the more efficient _LIT macro, which should be used instead. 

4.3 Reducing RAM Usage

There are a number of ways to reduce RAM usage. Some methods for doing this (suchas bit fields) can obfuscate code, so there is often a compromise to be struck betweenthe reduction in RAM usage and the increase in complexity of the code.

4.3.1 Use bit fields rather than many Tbools

Consider using bit fields to store large amounts of Boolean data in classes.Every TBool requires 32 bits of RAM, but that same 32 bits could hold 32Boolean values in a bit field. As mentioned above, compare the potential benefitsof this with the added code complexity.

4.3.2 Use caution with array granularities

All CArray-derived classes can specify granularity. This is to make code moreefficient by only allocating space for the array in certain size chunks. It iseffective, but some thought needs to go into the choice of granularity. If an arrayis needed for typically 5 to 8 objects, then a granularity of 4 or 5 is sensible. If the array always contains 15 objects, then the granularity should be 15.

However, if there are typically 2 or 3 objects, having a granularity of 100 wouldbe silly. Similarly, if there are typically 101 to 105 objects, a granularity of 100would be silly, as it would mean that 200 spaces are always allocated. However a granularity of 1 would also be silly, as it would involve many reallocations. Thefinal choice depends on the usage pattern.

4.3.3 Avoid global data

Don't use global data. Use local variables instead of member variables wherethey are only used in one function.

Version 1.0 | May 5, 2004

Page 53: Symbian OS Coding Conventions v1 0 En

8/4/2019 Symbian OS Coding Conventions v1 0 En

http://slidepdf.com/reader/full/symbian-os-coding-conventions-v1-0-en 53/58

Symbian OS: Coding Conventions in C++ | 53

4.3.4 Beware of base class member data

If you are writing a base class that is intended for wide use, use caution withmember data. Do not add member data that is only useful to some derivedclasses, as every derived class will have no choice but to own it. Take care to

only include truly generic member data.

4.3.5 Use the cleanup stack correctly

If the cleanup stack is used correctly, there should be no memory leaks in thecode – which in itself guarantees that the application is not using more RAM thanit needs to.

4.3.6 Delete early

If temporary objects are allocated on the heap, delete them as soon as they areno longer needed. If the life of temporary objects is longer than they are needed,

then the typical RAM consumption of the application will be higher than it needsto be. Remember, however, that if a temporary object is deleted while a pointer to it is still in scope, the pointer should be set to NULL to prevent illegal access or double deletions.

4.3.7 Test on hardware with the maximum data set

If a data set has an upper limit, then test on hardware with the maximum dataset. It is very easy not to notice that some operation is very slow, or causesproblems, if it is never tested on hardware at its limits. Always be sure to load uptest scenarios with large data sets.

4.3.8 Break up long, complex operations

Displaying long lists on screen can be a source of heavy RAM usage, and badperformance while the list controls are initialized (e.g., a list of all contacts or notes on the device). This can be avoided by writing specific controls, which onlypopulate the list with the entries that are visible on the screen. Scrolling thendeletes the entries that leave the screen and adds new ones.

4.4 Reducing Stack Usage

The stack available to an application on target hardware is smaller than the giant stackavailable to the emulator in the Windows NT environment. This can lead to code that

appears to run perfectly in the WINS/WINSCW emulator not running on the hardware, withapparently random panics. Reducing stack usage is not easy, but there are a couple of things to watch out for:

4.4.1 Use descriptors correctly

There are two types of descriptors: heap descriptors (HBufC) and stackdescriptors (TBuf). All descriptors use one of these types for storage. Whenthe stack overflows, 90 percent of the time it is caused by large descriptors onthe stack. Be aware of operations that cause implicit copying of descriptors, andavoid them where possible. It may be better in some situations to allocateHBufCs to work on rather than TBufs.

Version 1.0 | May 5, 2004

Page 54: Symbian OS Coding Conventions v1 0 En

8/4/2019 Symbian OS Coding Conventions v1 0 En

http://slidepdf.com/reader/full/symbian-os-coding-conventions-v1-0-en 54/58

Symbian OS: Coding Conventions in C++ | 54

Some related Symbian OS classes, such as TParse, can also use up a lot of stack space. Consider using alternative versions that use less stack space (e.g.,TParseBase).

Passing descriptors by reference is preferred to passing by value.

4.4.2 Beware of recursion, and build in limits

If recursive programming is necessary, be aware of the demands on the stack.Try to minimize the size of the parameters being passed down, and try to movelocal automatic variables out of the recursive part of the function. If at allpossible, build in a recursion depth limit to prevent the stack overflowing.

4.4.3 Beware of logging code

Logging code typically involves the formatting of long descriptors and their writing out to files. For this reason they are often the cause of stack overflows.

4.5 Low Disk Handling

There are two levels defined by the system monitoring the free space available on theFlash File System (FFS, alias the C: drive): Warning Level (WL) and Critical Level (CL).When free disk space meets one of these levels, the system (EikSrvUI) will display aglobal note, which warns the user about the situation. Applications and servers cantherefore ignore the Warning Level and concentrate on the Critical Level.

All operations that create or write to a file on disk with a known file size must first checkthe Critical Level with that size as a parameter to the FFSSpaceBelowCriticalLevelLmethod. If the disk space is already below, or going to go below, Critical Level, thismethod will return

ETrue. Applications must not write data and should indicate to the

user that the disk is full. (Leaving with the KErrDiskFull error code can achieve this.)

All operations that create or write to a file on disk with an unknown file size must checkthe Critical Level first, passing a good estimate of size or "0" (the default) as a parameter to the FFSSpaceBelowCriticalLevelLmethod. The zero can be used to checkwhether you are already below the critical level.

Cases where single items are created in databases (e.g., contacts) are difficult. Here, anestimate can be used of the increase in database size the item add would cause.

The Critical Level checking method is available in SysUtil.h/SysUtil.dll . Its APIlooks like this:

/*** Checks if the free FFS (internal Flash File System) storage* space is or will fall below Critical Level (CL).* The CL and FFS drive letter is defined by this module.* @param aFs File server session.* Must be given if available in the caller,* e.g. from EIKON environment.* If NULL this method will create a temporary session for* a check, but then the check is more expensive.* @param aBytesToWrite number of bytes the caller is about to add* FFS, if known by the caller beforehand.* The default value 0 checks if the current* space is already below the CL.* @return ETrue if storage space would go below CL after adding* aBytes more data, EFalse otherwise.* Leaves on error.*/

IMPORT_C static TBool FFSSpaceBelowCriticalLevelL(RFs* aFs,TInt aBytesToWrite = 0);

Version 1.0 | May 5, 2004

Page 55: Symbian OS Coding Conventions v1 0 En

8/4/2019 Symbian OS Coding Conventions v1 0 En

http://slidepdf.com/reader/full/symbian-os-coding-conventions-v1-0-en 55/58

Symbian OS: Coding Conventions in C++ | 55

5 . B u i l d i n g fo r A R M Ta rg e ts

5.1 General Issues

Building for ARMI will in general be more difficult than building for  WINS/WINSCW and it isnormal to find additional compiler errors and warnings from gcc on the first attempt. Thisis firstly because gcc is in many situations stricter than the Microsoft compiler, and alsohas some subtle differences that will come out the first time an ARMI build is attempted.The following sections cover a few of the most common pitfalls.

5.2 Function Exports

The gcc tool chain is stricter than that of  WINS/WINSCW when it comes to specifyingexported functions. The correct way to export a function from a DLL is as follows:

In the header file:

class CMyClass : public CBase{IMPORT_C void Function();}

and then in the CPP file:

EXPORT_C void CMyClass::Function(){}

The WINS/WINSCW tool chain does not mind if the EXPORT_C is excluded from the CPPfile; it exports the function anyway. However, the gcc tool-chain requires the IMPORT_Cand EXPORT_C to be perfectly matched. If they are not, the function will not be exportedfrom the DLL, which will eventually lead to errors such as "Cannot Find Function" whenattempting to link to this DLL.

5.3 The "MyDll.DLL has (un)initialized data" error from PETRAN

The Symbian OS architecture does not allow DLLs to have a data segment (static data,either initialized or uninitialized). There are problems with deciding what such a datasegment would mean:

Do all users of the DLL share it?

Should it be copied for each process that attaches to the DLL?

In addition, there are significant run-time overheads in implementing any of the possible answers.

However, because the WINS/WINSCW emulator uses the underlying Windows DLLmechanisms, it can provide per-process DLL data using "copy-on-write" semantics. Thisis why the problem goes undetected until the code is built for an actual Symbian OSdevice.

Consider this section of C++ code, added to a file QSORT.CPP, which is part of ESTLIB.DLL:

// variablesstruct div_t uninitialised1; // in .DATAstatic struct div_t uninitialised2; // in .BSS

Version 1.0 | May 5, 2004

Page 56: Symbian OS Coding Conventions v1 0 En

8/4/2019 Symbian OS Coding Conventions v1 0 En

http://slidepdf.com/reader/full/symbian-os-coding-conventions-v1-0-en 56/58

Symbian OS: Coding Conventions in C++ | 56

struct div_t initialised1 = {1,1}; // in .DATAstatic struct div_t initialised2 = {2,2}; // in .DATA

// constantsconst struct div_t const1 = {3,3};const static struct div_t const2 = {4,4};

const TPoint none(-1,-1);static const TText* plpPduName[12] =

{_S("Invalid"),_S("DataFlowOff"),_S("DataFlowOn"),_S("ConnectRequest"),_S("ConnectResponse"),_S("ChannelClose"),_S("Info"),_S("ChannelDisconnect"),_S("End"),_S("Delta"),_S("EndOfWrite"),_S("PartialWrite")};

When this code is built, the messages from PETRAN look something like:

PETRAN - PE file preprocessor V01.00 (Build 170) WARNING: Dll 'ESTLIB[10003B0B].DLL' has initialised data. WARNING: Dll 'ESTLIB[100002C3].DLL' has uninitialised data.

The associated .map file contains information that helps to track down the source fileinvolved.

Look in Symbian OS\release\arm4\urel\dllname.map.

Search for .data or .bss.

In this example, we find:.data 0x10017000 0x200

0x10017000 __data_start__=.*(.data).data 0x10017000 0x40 ..\..\SymbianOS\BUILD\STDLIB\BMMP\ESTLIB\ARM4\UREL\ESTLIB.in(QSORT.o)

0x10017000 initialised1*(.data2)*(SORT(.data$*))

0x10017040 __data_end__=.*(.data_cygwin_nocopy).bss 0x10018000 0x18

0x10018000 __bss_start__=.*(.bss)

.bss 0x10018000 0x18 ..\..\SymbianOS\BUILD\STDLIB\BMMP\ESTLIB\ARM4\UREL\ESTLIB.in(QSORT.o)0x10018008 uninitialised1

*(COMMON)0x10018018 __bss_end__=.

So the DLL has 0 x 18 bytes of uninitialized data (.bss) and 0 x 40 bytes of initializeddata (.data), all of which comes from qsort.o.

The variables initialised1 and uninitialised1 both have global scope, so the.map file lists them by name (and puts them both in the initialized data). The staticvariables don't get named in the .map file.

Version 1.0 | May 5, 2004

Page 57: Symbian OS Coding Conventions v1 0 En

8/4/2019 Symbian OS Coding Conventions v1 0 En

http://slidepdf.com/reader/full/symbian-os-coding-conventions-v1-0-en 57/58

Symbian OS: Coding Conventions in C++ | 57

Removing the first four lines of code shown above leaves just variables that are declaredas const, but only reduces .bss to 0x08 bytes, and .data to 0x30 bytes. There aretwo problems remaining:

1. Declaring C++ objects as const doesn't help if they have a constructor. The

8 bytes of uninitialized data are allocated to hold the TPoint object, but itwon't become const until after the constructor has completed.

2. The declaration const TText* says that the TText values may not bealtered, but it does not make the pointer a constant as well. The 48 bytes of initialized data are the 12 pointers in the plpPduName array. To make thepointers constant as well as the values they point to, the declaration needsan additional const after the TText*:

static const TText* const plpPduName[12] ={_S("Invalid"),_S("DataFlowOff"),_S("DataFlowOn"),_S("ConnectRequest"),_S("ConnectResponse"),_S("ChannelClose"),_S("Info"),_S("ChannelDisconnect"),_S("End"),_S("Delta"),_S("EndOfWrite"), _S("PartialWrite")};

Removing the TPoint global variable and adding the extra const to the plpPduName array finally removes the last of the offending .bss and .data.

Version 1.0 | May 5, 2004

Page 58: Symbian OS Coding Conventions v1 0 En

8/4/2019 Symbian OS Coding Conventions v1 0 En

http://slidepdf.com/reader/full/symbian-os-coding-conventions-v1-0-en 58/58

Symbian OS: Coding Conventions in C++ | 58

6 . Te rm s a n d A b b re v i a t i o n s

Term or abbreviation

Meaning

ARM ARM processor 

ARMI ARM 4 instruction set with Thumb interworking

ARM4 ARM 4 instruction set without Thumb interworking

GCC Compiler tool chain for ARM processor 

IDE Integrated Development Environment; a system for supporting theprocess of writing software, including a syntax-directed editor,graphical tools for program entry, and integrated support for compiling and running the program and relating compilation errorsback to the source. For example, Visual C++.

SDK Software Development Kit; set of programming tools for creatingapplications and enhancing the use of certain software.

THUMB ARM Thumb instruction set with ARM

WINS Refers to the target platform for the Microsoft Windows hostedemulator with Microsoft Visual C++ IDE

WINSCW Refers to the target platform for the Microsoft Windows hostedemulator with Metrowerks CodeWarrior IDE