quality in connection of symbian code presented by: abu rashid, student, researcher. april 1st, 2005

28
Quality in connection of Symbian Code Presented by: Abu Rashid, Student, Researcher. April 1st, 2005.

Upload: armani-whitcraft

Post on 14-Dec-2015

215 views

Category:

Documents


0 download

TRANSCRIPT

Quality in connection of Symbian Code

Presented by:

Abu Rashid,

Student, Researcher.

April 1st, 2005.

Contents

Quality Code Personal Quality Strategy Coding Conventions Critical part of Symbian OS programming Symbian Coding Standard Writing Good Code Internationalization, Cleanup Stack, Exception Handling in

Symbian OS C++ Guidelines to avoid memory leaks

What is quality code?

Definition Correct Efficient (time, space) Sufficient (for the task at hand) Understandable (readable, maintainable) Reusable Extensible Self Documenting Code

By means of ‘illities’ - reliability, maintainability, readability, enhance-ability, performability, scalability, etc. Due to some business factors some ’illities’ are sometimes magnified and some others ’sacrificed’.

Why quality code matters

Some Questions: What you ship to the user is the binary, not the source; nobody

outside your team ever cares to look at it. So does quality code really matters?

- ”..you will care if you have to maintain it..debug it... and you cost money. The business cares about that.”

Does quality in coding especially, naming convention results in measurable business returns?

Compilers also don’t care about source code quality

Some good discussions on quality of code:- What is good code? :

http://www.artima.com/forums/flat.jsp?forum=106&thread=96404- The Code Quality Myth:

http://www.artima.com/forums/flat.jsp?forum=106&thread=96154

Personal Quality Strategy

Watts S. Humphrey

Quality Stages –

Stage 1: Basic code quality: syntax and coding constructs- At this stage, quality is personal- Track, analyze and record the defects to improve the

personal level of basic code quality

Coding Conventions

A common mean to improve software quality Used to avoid and control the usage of problematic

characteristics in programming languages Unifies the appearances of source code Improves readability of the software, allowing engineers to

understand new code more quickly and thoroughly 80% of the lifetime cost of a piece of software goes to

maintenance Coding conventions are used to ease the programming itself.

Critical part of Symbian OS programming

The critical part of Symbian OS programming – Error Handling Cleanup Framework

We will discuss about these in details just after going through general coding conventions.

Symbian Coding Standard

General Rules: Reusability: Comments in code can make the code more

understandable and easier to read. However, if the code needs a lot of explanation, it is probably not clear enough.

Maintainability: [While writing the code] How will the other developers understand this code?

Build Process: You have to have very good reasons to ignore warnings.

Source Files: Filenames in lowercase, but with the first letters of words capitalized. Header files are kept in the directory ".\inc" or in directories mentioned

in the bld.inf file. Private header files in quotation marks (“”) and public headers are in

angle brackets (<>) in #include directives

Coding Conventions:

Use descriptive name for identifiers Use terminology applicable to the domain; if clients are actually

customers, then use customer Use mixed case to make names readable Use abbreviation sparingly and intelligently: ‘no’ or ‘num’ for

number Avoid long names (< 15 chars) Names such as sqlDatabase for an attribute or SqlDatabase for

a class are easier to read than sQLDatabase and SQLDatabase.

Coding Conventions: Continued

All names should be in English Join words, avoid numbers and abbreviations in names Never use ‘_’. Exception: preprocessor macro names in #define Automatic variables: declare when required, initialize when they are

declared rather than assigning values to them

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

Never initialize or instantiate multiple items on the same line.

Coding Conventions: Continued

Control Structures: switch() must have a default: clause and avoid ‘case’ without a break statement. Use braces ({ }) for if (), else, while (), do..while (), for (), even if there is only a single statement or an empty block.

Class names: <Symbian OS prefix><Project prefix>Name

Symbian OS prefix: C (heap-allocated class derived from a base class CBase) R (resource class containing handles to a real resource, which

is maintained elsewhere) T (simple type) M (mix-in class / interface class) Use references in preference to pointers

Coding Conventions: Continued

Functions: Parameter names with ‘a’ (argument) prefix Use const attribute when a method does not need to change the

parameter Use trailing L(function that may leave), C(places item on the cleanup

stack) or D(destroys the object in question) to the function name where appropriate

static CMyClass* newLC(); // may leave and places an item on stackTInt ExecuteLD(TInt aResource); //may leave and will destroy the object

Automatic variables: Do not declare until required Never initialize multiple items on the same line

Coding Conventions: Continued

Global variables: Use of global variables is discouraged Start names with a capital letter. If the letter has to be H/T/C, then ‘g’ as prefix,

e.g. gWhateverMacros: All capitalized Underscore separated words, e.g. IMPORT_C, _TEST_INVARIANT Avoid #defineS, use real constants instead -

const TInt KMagicNumber = 42;Constants: Preceding K uppercaseEnumerated types: T prefix, uppercase E prefix for enum members Class CTetrisBlock { enum TBlockType {ESquareBlock, ELBlock};};Copyright messages: Copyright (c) 1997-2005 Symbian Ltd. All rights reserved.

Coding Conventions: Continued

Asserts, Panics & Class Invariants: __ASSERT_ALWAYS & __ASSERT_DEBUG test macros can prevent

many problems- Many error condition will not trip up the application straight

away, but will lead to side effects later. So check for parameters coming into functions, null pointers and other error conditions

// Removes text content, commencing at position aPos, over aLength

// number of characters void CComplexTextObject::Delete(TInt aPos,TInt aLength) { __TEST_INVARIANT; __ASSERT_ALWAYS(aPos>0,Panic(EPosOutsideTextObject)); iTextBuffer->Delete(aPos,aLength); __TEST_INVARIANT; }

Coding Conventions: Continued

Multi-inheritance: Only M classes may be used in multi-inheritance. Only the interface may be inherited. Therefore all M classes must be

pure virtual. Inherit from the CBase-derived class first to achieve the correct layout

of the v-table –class CDerivedClass : public CBase, public

MSomeObserver

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 the TCleanupItem class.

Never push member data on the cleanup stack.

Coding Conventions: Continued

Class Design: Use references in preference to pointers Use least derived class possible

Class layout: Always write access control specifiers; special member function at the

top List the public methods first List public member data before private member data Obey the indentation convention

Coding Conventions: Continued

Virtual function: Virtual functions that replace inherited behavior should be grouped

together in the header with a comment documenting which class the behavior is inherited from

It is not necessary to specify the virtual keyword for these functions Do not make virtual functions inline, but inline virtual destructor is

ok.

Inline functions: specify inline explicitly for inline functions do not implement the inline implementation in the class definition;

this confuses and pollutes the header, making it less readable provide inline implementations at the bottom of the header or in a

separate .inl file

Writing Good Code

Build code that gives 0 compiler warnings and 0 link errors Be consistent in the use of programming conventions Strive to write tight, efficient code Minimize on stack usage Minimize on the number of calls to the allocator Always ask... what would happen if this code were to leave? Avoid hard-coding magic numbers; use constants or

enumerations.

Internationalization

Rule of thumb: do not hard code anything that is visible in the user interface – all text, filenames, sounds, time and date, etc.

Descriptors and charsets – TPtr class should be used for strings Text – use logical names Graphics and screenlayout – avoid using text in UI elements; if

text is really needed for graphics, use a text string on top of graphics. Do not hardcode string sizes

Locale specific data – hardcoded language or country-dependent information such a date, time, currency, etc. should not be used. Use AVKON resources wherever possible.

Font – Use a resource file and refer the fontname by its logical name.

Exception Handling in Symbian OS C++

Symbian OS applcations are designed to run for years without needing to reboot, and on memory constrained devices, so an out-of-resource error is more likely to occur than in desktop applications

Conventional error checking(using if statement to check for out-of-resource) is not used because: introduces many extra lines of code, if a constructor fails to allocate resources, there is no way to return an error code as constructors have no return value.

C++ exception handling (try, catch and throw) is also not used

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

Exception Handling in Symbian OS C++

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

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

// Do some error code }

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

if ( !myObject ) User::Leave(KErrNoMemory);

Symbian OS efficient exception handling rules

Rule 1: Functions that can leave should have a letter L at the end of their names.

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

Rule 2: While allocating memory on the heap, if the pointer is an automatic variable, it should be pushed on the cleanup stack.

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

Rule 3: All the codes that might fail, should be taken out of the constructor, and put into a constructL() function. This will be called after the constructor has completed. This is two-phase construction.

Symbian OS efficient exception handling rules: Continued

// Phase #1 MyObject::MyObject() { } // Phase #2 void MyObject::ConstructL() {

MyMemberData* data = new (ELeave) MyMemberData(); } // Put both phases together in one function... MyObject* MyObject::NewL() {

MyObject * self = new (ELeave) MyObject(); CleanupStack::PushL(self); self->ConstructL(); CleanupStack::Pop(self); return self;

}

Symbian OS efficient exception handling rules: Continued

Note – The applcation framework already provides traps in

right places, and code to handle them, so traps should not be used in normal coding.

The new operator is overriden to take a parameter ELeave. In case of memory allocation failure, this overriden constructor will leave.

When creating C-class objects, programs should use newL() if a member variable will point to the object, newLC(), if an automatic variable will point to it

Using the Cleanup Stack: Why it is needed

When a function leaves, the default TRAP harness inside the the thread’s Active Scheduler gets control. So all automatic variables within the function are destroyed. If anyone pointed to object, then that object is orphaned and memory leak follows. Solution -> Cleanup Stack.

Automatic variables are used to point C-class objects; objects are pushed onto the cleanup stack using CleanupStack::PushL() and popped from it using CleanupStack::PopL(). PopAndDestroy() is normally used instead of Pop().

Object data members which point to other objects must not be pushed onto the cleanup stack.

Guidelines to avoid memory leaks

Understand the cleanup stack and the Leave/TRAP paradigm. Build and run code regularly — if a leak appears, it will be more

obvious where it was caused. When testing, exit the application. Don’t just kill the emulator. Code reviews are very useful.

Reduce RAM usage: Use bit fields rather than many Tbools Use caution with array granularities Avoid global data Beware of base class member data Use cleanup stack correctly Delete early Test on hardware with maximum datasets Break up long, complex operations

Thanks for your time. Questions?

References Harrison, Richard: Symbian OS C++ for Mobile

Phones Symbian; Symbian OS: Coding conventions in

C++, May 5, 2004 Symbian; Coding idioms for Symbian OS, Oct

2002 Symbian; Symbian OS C++ coding standard,

Jan 2003 Halonen & Närvänen & Mikkonen: Automatic

checking of Symbian Coding Conventions. Humphrey, Watts S.: A personal quality strategy