Sie sind auf Seite 1von 79

TMA Training Center

C/C++ Coding Guideline


SW-GU-003
Version 1.0

TMA Training Center


Issue Date: Apr 12, 06

C/C++ Coding Guideline

Code: SW-GU-003
Version: 1.0

Table of Contents
1. Introduction.......................................................................................................................................................
1.1 Purpose......................................................................................................................................................
1.2 Scope..........................................................................................................................................................
1.3 Definitions, Acronyms and Abbreviations.................................................................................................
1.4 References..................................................................................................................................................
2. Overview...........................................................................................................................................................
3. Comment Convention........................................................................................................................................
Rule 1: Always use documentation comment immediately before declaration..............................................
Rule 2: Do not use C-Style comment.............................................................................................................
Rule 3: Always use comment with //............................................................................................................
Rule 4: Do not leave commented out software in a file................................................................................
Rule 5: Do not include anything except description in comment.................................................................
Rule 6: Do not put comment at the end of line.............................................................................................
4. Naming Convention.........................................................................................................................................
Rule 1: Always capitalize the first letter and letters as word separators of name only................................
Rule 2: Do not use acronyms in names unless the acronym is defined in user document...........................
Rule 3: Always use verb for first word and use verb opposites for opposite actions...................................
Rule 4: Always include a prefix on global and namespace names...............................................................
Rule 5: Always include a prefix on member name.......................................................................................
Rule 6: Always include a prefix on local name............................................................................................
Rule 7: Always 1st letter is lowercase and only letters as word separators is uppercase.............................
Rule 8: Do not include any underscore in name except after variables prefix............................................
Rule 9: Always make all letters of name uppercase.....................................................................................
Rule 10: Always make a combination of plane words by using underscore ( _ ).........................................
Rule 11: Do not pluralize enumerated type name.........................................................................................
Rule 12: Never use number as word.............................................................................................................
Rule 13: Always make sure that argument names and its purposes are the same........................................
Rule 14: Always name header and implement files the same as class name................................................
5. Format Convention..........................................................................................................................................
Rule 1: Always indent new scope with two additional spaces.....................................................................
Rule 2: Do not allow line to exceed 80 characters.......................................................................................
Rule 3: Always use space instead of tab.......................................................................................................
Rule 4: Do not code more than one statement per line.................................................................................
Rule 5: Always add one more empty line between each section..................................................................
Rule 6: Always make level alignment of every code section.......................................................................
Rule 7: Always put pair of braces around statement on new line even single line of code..........................
6. Constant Convention.......................................................................................................................................
Rule 1: Do not use #define to create the constant........................................................................................
Rule 2: Do not use #define to create method-like macros............................................................................
Rule 3: Always declare the constant when possible.....................................................................................
Rule 4: Always define constant for literal except 0, 1 and true, false..........................................................
7. Operator Convention.......................................................................................................................................
Rule 1: Do not add a white space between unary operator and its operand.................................................
Rule 2: Always add a white space before and after to operators..................................................................
Rule 3: Do not use ? operator.......................................................................................................................

TMA Confidential

TMA Solutions, 2004

Page 2 of 79

TMA Training Center


Issue Date: Apr 12, 06

C/C++ Coding Guideline

Code: SW-GU-003
Version: 1.0

8. Control Flow Convention................................................................................................................................


Rule 1: Do not change a loop variable inside for loop block.......................................................................
Rule 2: Always add default for switch statement.........................................................................................
Rule 3: Always follow the sample of statements as following form............................................................
Rule 4: Do not use goto keyword to replace control flow statements or other purposes.............................
9. Expression Convention....................................................................................................................................
Rule 1: Always avoid embedding the assignment within another expression.............................................
Rule 2: Should put the constant, TRUE/FALSE, .. on the left of comparison expression..........................
Rule 3: Do not use integer variable as bool variable in conditional expression...........................................
Rule 4: Always include parenthesis in expression if possible......................................................................
Rule 5: Always separate operators groups from parenthesis.......................................................................
10. Pointer and Memory Management Convention............................................................................................
Rule 1: Do not use malloc, free, calloc, realloc, and ... operators from standard C.....................................
Rule 2: Always use new and delete operators consistently and accurately..................................................
Rule 3: Always check existence of pointer before using it...........................................................................
Rule 4: Should use 0 instead of NULL.........................................................................................................
Rule 5: Should implement exception handling as needed............................................................................
Rule 6: Should use exception handling instead of status value and error code............................................
11. Variable and Data Types Convention.............................................................................................................
Rule 1: Should use unsigned data type when value can not be negative......................................................
Rule 2: Do not have method and non-public variable members in a structure.............................................
Rule 3: Always postpone variable definition as long as possible.................................................................
Rule 4: Do not use the same variable name in outer and inner scopes.........................................................
Rule 5: Do not declare member variables as non-private.............................................................................
12. Method Convention.......................................................................................................................................
Rule 1: Always order method arguments as follows: input, input and output, and output...........................
Rule 2: Do not pass class and structure arguments by value........................................................................
Rule 3: Always name method arguments.....................................................................................................
Rule 4: Always place return statement at the last line of method.................................................................
Rule 5: Always specify return type explicitly even though default type is int.............................................
Rule 6: Do not return pointer and reference to local variable......................................................................
Rule 7: Always call static method using CLASSNAME::[static method] format........................................
Rule 8: Do not use inline method when they are not really needed.............................................................
Rule 9: Do not create method that have more than seven arguments...........................................................
Rule 10: Always include a white space after a comma................................................................................
Rule 11: Do not add a white space after method name when calling method..............................................
Rule 12: Do not use unspecified arguments ()..........................................................................................
13. Class Convention...........................................................................................................................................
Rule 1: Should declare public, protected and private in this order and only one time.................................
Rule 2: Always order items in an access section..........................................................................................
Rule 3: Do not place anything in protected section except base class..........................................................
Rule 4: Do not place member variables in public access section.................................................................
Rule 5: Always initialize all class member variables in initialization list....................................................
Rule 6: Always ensure the order of variables in declaration and in init list are the same............................
Rule 7: Always make base class destructor virtual......................................................................................
Rule 8: Mark virtual for method in derived class when method is virtual in base class..............................
Rule 9: Do not let compiler generate default constructor.............................................................................
TMA Confidential

TMA Solutions, 2004

Page 3 of 79

TMA Training Center


Issue Date: Apr 12, 06

C/C++ Coding Guideline

Code: SW-GU-003
Version: 1.0

Rule 10: Should declare a copy constructor and assignment operator.........................................................


14. Header and Implement Files Convention......................................................................................................
Rule 1: Do not include unnecessary header file...........................................................................................
Rule 2: Should not use path in #include statement.......................................................................................
Rule 3: Should not put methods implementation in header file even inline method...................................
Rule 4: Should separate inline methods definition from implementation...................................................
Rule 5: Always use forward declaration instead of #include if possible......................................................
Rule 6: Dont define non-static variable in header file except constant variable.........................................
Rule 7: Do not define an aggregate variable or member in a header file even constant..............................
Rule 8: Always separate each class from specific header and implementation files....................................
15. Class Design Convention..............................................................................................................................
Rule 1: Should consider the following class design checklist as critical need.............................................
Rule 2: Should use destructor to prevent resource leaks..............................................................................
Rule 3: Should avoid resource leaks in constructors....................................................................................
Appendix: C++ Keywords..................................................................................................................................

TMA Confidential

TMA Solutions, 2004

Page 4 of 79

TMA Training Center


Issue Date: Apr 12, 06

C/C++ Coding Guideline

Code: SW-GU-003
Version: 1.0

1. Introduction
1.1 Purpose
This document defines C/C++ Coding Standards. These standards lead to consistency and help software
engineers avoid common problems. A development environment that uses C/C++ standards has the following
advantages:
Developers can view any C/C++ software and quickly figure out whats going on.
Developers new to C/C++ are spared the need to develop a personal style.
Developers make fewer mistakes in consistent environments.
Discussions about the appropriateness of software are reduced at reviews.
These guidelines are expected to be adhered to in all future C/C++ software development for the
project.
Existing code will not be required to be rewritten to adhere to these guidelines, but it is suggested that
reasonable efforts are made to adhere to the new guidelines when working on existing code.

1.2 Scope
This document is written specifically for all project of TMA coding in C/C++ language, so it is meant to be as
generic as possible. Because each project can have its own programming standard, so we can change this
standard to be consistent with customer requirements.
In any case, the standard cannot cover every issue of C++ programming, and cannot always match the
different choices that different experiments/projects have made on certain issues. Therefore the different
experiments/projects should, if necessary, tailor this standard to their specific quality requirements; this could
mean to suppress an item or to add additional items.
Each section of this document contains recommended standards in that area, along with a further list of
guidelines. A standard is required to be followed in all future development. If a programmer must violate a
standard, then the reason for doing so must be strong and clearly documented via code comments. Guidelines
are just that.
Individual programmers are encouraged to program in a style which is consistent with the rest of the
programming team, but differing code styles could be acceptable.
These standards recognize that individual programmers have the right to make judgments about how best to
achieve the goal of code clarity. When working on others code, please respect and continue existing styles
which, although they may differ from your own, meet these guidelines. This in turn leads to what is perhaps
the most important aspect of coding style: consistency. Try as much as possible, to use the same rules
throughout the entire program or module.

1.3 Definitions, Acronyms and Abbreviations


SPI
Item
Standard
ISO
CMM
OOP

Software Process Improvement.


Single statement addressing a specific issue.
Collection of items addressing the same subject.
International Standard Organization
Capability Maturity Model
Object Oriented Program

1.4 References
[1] Optivity Telephony Manager C++ Coding Standards Kyle Blaney 2002/05/10
[2] Coding Standard (Volume Visual C++) 2002/08/07

TMA Confidential

TMA Solutions, 2004

Page 5 of 79

TMA Training Center


Issue Date: Apr 12, 06

C/C++ Coding Guideline

Code: SW-GU-003
Version: 1.0

[3] C++ Coding Standard Specification S.Paoli 2000/01/05


[4] C++ How to Program 3rd Dr. Harvey M. Deitel and Paul J.Deitel 2001
[5] More Effective C++ Scott Meyers 1996
[6] HotDocument tool for C/C++ comment conventions

TMA Confidential

TMA Solutions, 2004

Page 6 of 79

TMA Training Center


Issue Date: Apr 12, 06

C/C++ Coding Guideline

Code: SW-GU-003
Version: 1.0

2. OVERVIEW
This document is organized to many sections. In every section, the rules are formatted as following form:
Rule ##: Name of rule.
Description
This rule is ONLY applied for specific cases or accepted from SOME.
Justification
Why we use this rule?
Example
Give out lines of sample codes which explain to the rule.
Comment Convention: In this section, you stand a good chance to learn how to comment software meet the
standard.
Naming Convention: Name is called, its said that an intent name is considered carefully before naming. So
why we have not to make a standard name? In this section, you will learn how to name a variable, a method, a
class and so on.
Format Convention: Studies have shown that developers have strong expectations about what software
should look like. With format convention your software will be neat and look professional.
Constant Convention: The purpose of this section is to name constant consistently.
Operator Convention: Just at a glance, this section is to give a form of operators should follow.
Control Flow Convention: In section, you will learn samples of control flow and something you should
avoid.
Expression Convention: Expression is combination of operators, its operands and others. Every operator
has its priority. As developer you have a lot of things to remember. Why you must put this mess thing in your
mind. Following these rules in this section, you can be easy to recognize the processing order of expression.
And avoid some unexpected errors!
Pointer and Memory Management Convention: Memory management is endless matter of C++ language.
How to overcome this matter? You can recognize easily how to do in this section.
Variable and Data Type Convention: Variable is not dropped out. Yes, but you have to utilize its steps as
much as possible. This section is to improve ways of using variable and data type as well.
Method Convention: You can be easy to know that method is the core of OOP. C++ is a strong language
supporting OOP. So method convention is a need of C++ coding standard. In this section, you will learn how to
organize your methods effectively.
Class Design Convention: The purpose of this section is to give out valuable ideas that you can take it
together when designing class.

Rule 0: Every time a rule is broken, this must be clearly documented.

3. COMMENT CONVENTION
Rules in this section ensure that software is formatted in a consistent comment. Following these rules, it is
easy for fixers to fix potential bugs and for designers to upgrade production. The following are rules talking
about comment.
Rule 1: Always use documentation comment immediately before declaration.
Description

Apply to interfaces, class, member function, and field.

Justification

This rule exists to create external documentation for a class.

Example

The following are samples:


For method:
/**

TMA Confidential

TMA Solutions, 2004

Page 7 of 79

TMA Training Center


Issue Date: Apr 12, 06

C/C++ Coding Guideline

Code: SW-GU-003
Version: 1.0

* ---------------------------------------------------------------* Method Name: <<Name of method>>


* Description: <<What the method does>>
* @Params: <<NONE or every params are explained in clear English>>
* @Return: <<NULL or every values in detail explanation if any>>
* @Exception: <<NONE or every exception if any>>
* Note: <<Put your notes here carefully>>
* ---------------------------------------------------------------*/

For class:
/**
* ------------------------------------------------------------* Class Name: <<Name of class>>
* Description: <<Whats intent of class>>
* Copyright: Copyright (c) <<YYYY/MM/DD>>
* Company: <<TMA - Software Solutions Vietnam>>
* @author: <<Who takes care this class>>
* @version <<1.0>>
* Note: <<Put your notes here carefully>>
* ------------------------------------------------------------*/

For function (Use HotDocument tool)


//******************************************************
//
// Function Name : pStrInstr
//
// Description : Return index of character in string
//
// Return Values : - index of character
//
-When character not exists, return 0
// Notes : pStrInStr( "a#c#d#eeee", "#" )
-> 2
//
pStrInStr( "a#c#d##eeee", "##" ) -> 6
//
pStrInStr( "abcdeabcde", "AA" ) -> 0
//
// Authors : BillGates
//
//********************************************************

intpStrInStr(constchar*tarstr,//Searchtargetstring
constchar*srcstr)//Searchstring
{
return 0;
}

Rule 2: Do not use C-Style comment.


Description

Apply to all objects.

Justification

Sometime you want to temporarily turn it off somehow while debugging.

Example

The following do not comply:


/*
This code was commented out by Bang Mai on Feb 21, 2002.
CR: 009999
Area: WINCS
*/

TMA Confidential

TMA Solutions, 2004

Page 8 of 79

TMA Training Center


Issue Date: Apr 12, 06

C/C++ Coding Guideline

Code: SW-GU-003
Version: 1.0

- Avoid Block style comments.


Block Style:
/*
* .................... AVOID THIS!
* ..................... AVOID THIS!
*/

Please look in the other rules in this section for more information
Rule 3: Always use comment with //.
Description

Apply to section of code, and declaration of temporary variable.

Justification

This rule is to make clear what section of code does and what temporary variables purpose
is.

Example

The following comply:


//This section is to update all systems.
// Get list of systems
int i_size = GetSize();
for (int i = 0; i < i_size; i++)
{
// Get type of current system
int i_type = GetType();
// Execute survivable cabinet system
if (i_type == 0)
{
}
// Execute main M1 system
else if (i_type > 0)
{
}
// Execute CSE system
else
{
}
}

Please look in the other rules in this section for more information
Rule 4: Do not leave commented out software in a file.
Description

Apply to all objects.

Justification

Commented out software obscures behavior. If developers fail to notice that a block of
software is commented out, they will misunderstand the softwares behavior. In addition, it is
difficult for a file comparison tool to get an accurate representation of the changes made
when software is commented out. To the file comparison tool, it appears that one section of
software was modified and another section was added. This is not what actually happened.
Rather, only one section was modified.
Sometimes, old versions of software are left (commented out) in a file so that a reader can

TMA Confidential

TMA Solutions, 2004

Page 9 of 79

TMA Training Center


Issue Date: Apr 12, 06

C/C++ Coding Guideline

Code: SW-GU-003
Version: 1.0

have an idea of the history of changes to the file. This should not be done because
maintaining a history of changes is a job already performed by a projects software revision
control system(Source Safe, Clear Case, and so on). There is no reason to duplicate the effort
of this tool.
Example

The following comply:


typedef void (FAR *MDRCorpdbTypes)(LPCTSTR);

The following do not comply:


// typedef void (FAR *RTCToIM)(LPCTSTR, char *);
typedef void (FAR *MDRCorpdbTypes)(LPCTSTR);

Rule 5: Do not include anything except description in comment.


Description

Apply to all objects.

Justification

Comments that indicate when and by whom software was changed are not necessary because
that information is stored by the revision control system.

Example

The following do not comply:


//
//
//
//

This code was commented out by Bang Mai on Feb 21, 2002.
CR: 009999
Area: WINCS
This section is to execute background service for Web component.

The following comply:


// This section is to execute background service for Web component.

Rule 6: Do not put comment at the end of line.


Description

Apply to all comments EXCEPT intentional fall-through in case statements or other tablebased software, and #include statements.

Justification

Endline comments have the following problems:


It takes time to align them.
They are difficult to maintain. If the software on any line containing an endline
comment grows, it may push the comment out further, and all the nearby endline
comments may also require modifications.
It is hard to write a meaningful comment for a single line of software.

Example

The following comply:


// We shift by 6 bits because 2 ^ 6 = 64.
const unsigned int numBitsToShift = 6;
num <<= numBitsToShift;

The following do not comply:


const unsigned int numBitsToShift = 6; // 6 bits because 2 ^ 6 = 64.
num <<= numBitsToShift; // shift the required number of bits

TMA Confidential

TMA Solutions, 2004

Page 10 of 79

TMA Training Center


Issue Date: Apr 12, 06

Code: SW-GU-003
Version: 1.0

C/C++ Coding Guideline

The following also comply:


#include DisplayException.h //Exception handling stuff
#include EventLog //Event log handling stuff
//Communication Configuration Parameter
struct COMM_CONFIG_PARAM
{
short
sdiPort;
// SDI Port Number
char
modemPhone[32]; // Switch Modem Phone Number
short
pcModemType;
// Modem Type (Regular, Call Back, Com Dev)
short
m1ModemType;
// Modem Type (Regular, Call Back, Com Dev)
short
bufferType;
// Buffer Type
short
baud;
// Baud Rate
short
stopBits;
// Stop Bits
short
parity;
// Parity
short
dataBits;
// Data Bits
short
vommPort;
// Com Port
short
timeOut;
// Time Out
short
delay;
// Delay
char
modemPassword[MAX_LENGTH]; // ModemPassword
char
customM1Modem[MAX_LENGTH]; // Custom M1 Modem Name
char
customPCModem[MAX_LENGTH]; // Custom PC Modem Name
char
filler1[MAX_ROOM];
// extra room for new info
}

Definition of structure:
Use the typedef to define the separate name of structure as below
typedef struct{

// Received

Comment of structure

long lLen;

// xxxxxxxxx

Declaration of Member

long lProcNo;

// xxxxxxxxx

long lParamCnt;

// xxxxxxxxx

long lParamLen;

// xxxxxxxxx

}MULTIPOINT;

Name

Define alias of structure

Definition of Class Interface


class CVsClientSocket : public XXXX // Socket
{
public:
// Property
BOOL

m_fMaxByte;

// XXXXXX

CHAR

m_chSend;

// XXXXXX

LONG

GetReceive();

Declaration of Property

// Member function

CVsClientCtrl ();

// XXXXXX

Declaration of Method

// Constructor

~CVsClientCtrl ();

// Destructor

protected:
LONG

CheckReceive(LONG lLen);

// XXXXX Declaration of Internal

private:
}

TMA Confidential

TMA Solutions, 2004

Page 11 of 79

TMA Training Center


Issue Date: Apr 12, 06

C/C++ Coding Guideline

Code: SW-GU-003
Version: 1.0

4. NAMING CONVENTION
Rules in this section ensure that software is formatted in a consistent name. Why we make the consistent
name, because name is the heart of programming and if name is exposed, then you will know its own implied
purpose. The following are rules talking about naming.
Rule 1: Always capitalize the first letter and letters as word separators of name only
Description

Justification

Example

Use capital for the first letter of each word boundary.


Function names must identify as far as possible the action performed or the information provided by the
function.
Apply to class, enum, and method.
Following this rule source code look neat and they are easy to distinguish
from variables which always start with a lowercase letter, struct and union which always is uppercase.
The following comply:
class TmaNamingForClass;
enum TmaNamingForEnum;
Author Book::GetAuthor(int BookId);

The following do not comply:


class TMANamingForClass;
enum TmaNamingForEnuM;
Author Book::getAuthor(int BookId);

Class name
Aa

1 Class Identifier Fixing withC


2 System Code

(depends on project)

3 Option (Refer to Basic Naming Recommendation in Appendix )

Member variable name

1. Member var identifier


Local var .
Global var .
2. Use Hungary naming method to express data type.
3. Alphabet (Refer to Basic Naming Recommendation)
Member function name

Alphabet (Refer to Basic Naming Recommendation in Appendix)

TMA Confidential

TMA Solutions, 2004

Page 12 of 79

TMA Training Center


Issue Date: Apr 12, 06

C/C++ Coding Guideline

Code: SW-GU-003
Version: 1.0

Rule 2: Do not use acronyms in names unless the acronym is defined in user document.
Description

Apply to class, enum, and variable.


(See Basic Naming recommendations in Appendix)

Justification

Using acronyms without definition make software hard to read and understand.

Example

The following comply:


class DepartmentalServicePerson : public Employee
{
}
enum WorkingDays
{
}

The following do not comply:


class Dsp : public Employee // should declare in clear name
{
}
enum WDays // should declare in clear name
{
}

Rule 3: Always use verb for first word and use verb opposites for opposite actions .
Description

Apply to method only.


Pairs of verb opposites are get/set, read/write, and so on.
(See Basic Naming recommendations in Appendix)

Justification

This rule exists for consistency

Example

The following comply:


class DepartmentalServicePerson : public Employee
{
public:
Color GetColor();
void SetColor(const Color color);
private:
BOOL IsLeapYear(Year year);
}

The following do not comply:


class DepartmentalServicePerson : public Employee
{
public:

TMA Confidential

TMA Solutions, 2004

Page 13 of 79

TMA Training Center


Issue Date: Apr 12, 06

C/C++ Coding Guideline

Code: SW-GU-003
Version: 1.0

Color GetColor();
void WriteColor(const Color color);//should use verb Get
private:
BOOL LeapYear(Year year); //should begin with verb
}

Rule 4: Always include a prefix on global and namespace names.


Description
Justification

Do not apply to member and local variables


(See Hungarian Naming method in Appendix)
This rule is to distinguish global variable from class, enum, method, member variable, and
local variable.
Prefix:
g for global
n for namespace
s for static
p for pointer
r for reference
a for array
Order:
For global: gsp(r)a,
For namespace: nsp(r)a
Note: After prefix(es), a underscore( _ ) is added.

Example

The following comply:


//Global variables
int g_numItems = 10;
int &gr_numItems = g_numItems;
int *gp_numItems = &g_numItems;
int ga_numItems[] = {1, 2, 3};
static int gs_numItems = 10;
static int &gsr_numItems = gs_numItems;
static int *gsp_numItems = &gs_numItems;
static int gsa_numItems[] = {1, 2, 3};
// Namespace variables
namespace ArbitraryNamespace
{
int n_numItems = 10;
int &nr_numItems = n_numItems;
int *np_numItems = &n_numItems;
int na_numItems[] = {1, 2, 3};
static int ns_numItems = 10;
static int &nsr_numItems = ns_numItems;
static int *nsp_numItems = &ns_numItems;
static int nsa_numItems[] = {1, 2, 3};
}

TMA Confidential

TMA Solutions, 2004

Page 14 of 79

TMA Training Center


Issue Date: Apr 12, 06

C/C++ Coding Guideline

Code: SW-GU-003
Version: 1.0

The following do not comply:


//Global variables
int numItems = 10; //should prefix g_
int &r_numItems = numItems; //should prefix gr_
int *p_numItems = &numItems; ////should prefix gp_
int g_numItems[] = {1, 2, 3}; ; //should prefix ga_
static int s_numItems = 10; //should prefix gs_
static int &gs_numItems = gs_numItems; //should prefix gsr_
static int *sp_numItems = &gs_numItems; //should prefix gsp_
static int gs_numItems[] = {1, 2, 3}; //should prefix gsa_
// Namespace variables
namespace ArbitraryNamespace
{
int numItems = 10; //should prefix n_
int &r_numItems = numItems; //should prefix nr_
int *p_numItems = &numItems; //should prefix np_
int a_numItems[] = {1, 2, 3};//should prefix na_
static int n_numItems = 10; //should prefix ns_
}

Rule 5: Always include a prefix on member name.


Description
Justification

Apply to member variable and method argument


(See Hungarian Naming method in Appendix)
This rule is to distinguish member variable from class, enum, method, global variable and
local variable.
Prefix: m
s for static
ch for char
w for WORD
h for HANDLE

p for all pointers


str for CString
dw for DWORD
v for VARIANT

r for reference
b for BOOL, bool
d for DOUBLE,double
i for BYTE, UINT,int

a for array
l for LONG,long
f for FLOAT,float
bstr for BSTR

Order: m[s][p, r, a] or m[s][b, i, str, ch]


Example: msp, msr, msa, msb, msh,
Note: If the member variable is p, r, or a, we do not prefix anything more except s. After
the prefix(es), a underscore( _ ) is added.
Example

The following comply:


class ArbitraryClass
{
public:
void Copy(Car *p_destination, Car *p_source);
private:
int mi_numItems;
int &mr_numItems;
int *mp_numItems;
int ma_numItems[numElementsInArray];
static int msi_numItems;
static int &msr_numItems;

TMA Confidential

TMA Solutions, 2004

Page 15 of 79

TMA Training Center


Issue Date: Apr 12, 06

C/C++ Coding Guideline

Code: SW-GU-003
Version: 1.0

static int *msp_numItems;


static int msa_numItems[numElementsInArray];
CString mstr_name;
DWORD mdw_age;
};

The following do not comply:


class ArbitraryClass
{
public:
void Copy(Car *destination, Car *source); //should prefix p_
private:
int i_numItems; //should prefix mi_
int &m_numItems; //should prefix mr_
int *mpg_numItems; //should prefix mp_
int a_numItems[numElementsInArray]; //should prefix ma_
static int mi_numItems; //should prefix msi_
static int &ms_numItems; //should prefix msr_
static int *ms_numItems; //should prefix msp_
static int ms_numItems[numElementsInArray]; //should prefix msa_
CString m_name; //should prefix mstr_
DWORD m_age; //should prefix mdw_
};

Rule 6: Always include a prefix on local name.


Description
Justification

Apply to local variable


(See Hungarian Naming method in Appendix)
This rule is to distinguish local variable from class, enum, method, global variable and
member variable.
Prefix:
s for static

p for all pointers

r for reference

a for array

Order: [s][p, r, a]
Example: sp, sr, sa
Note: After the prefix(es), a underscore( _ ) is added.
Example

The following comply:


void ArbitraryClass::PerformAction()
{
int numItems = 10;
int &r_numItems = numItems;
int *p_numItems = &numItems;
int a_numItems[] = {1, 2, 3};
static int s_numItems = 10;
static int & sr_numItems = s_numItems;
static int *sp_numItems = &s_numItems;
static int sa_numItems[] = {1, 2, 3};

TMA Confidential

TMA Solutions, 2004

Page 16 of 79

TMA Training Center


Issue Date: Apr 12, 06

C/C++ Coding Guideline

Code: SW-GU-003
Version: 1.0

CString name;
CString strName;
DWORD age;
DWORD dwAge;
};

The following do not comply:


void ArbitraryClass::PerformAction()
{
int i_numItems = 10; //should prefix nothing
int &numItems = numItems; //should prefix r_
int *pi_numItems = &numItems; //should prefix p_
int arr_numItems[] = {1, 2, 3};//should prefix a_
static int numItems = 10; //should prefix s_
static int &r_numItems = s_numItems; //should prefix sr_
static int *s_numItems = &s_numItems; //should prefix sp_
static int a_numItems[] = {1, 2, 3};//should prefix sa_
CString str_Name; //should prefix str (strName)
DWORD dw_Age; //should prefix dw (dwAge)
};

Rule 7: Always 1st letter is lowercase and only letters as word separators is uppercase.
Description

Apply to method name.

Justification

This rule is to distinguish variable from class, struct, union, enum, and method.

Example

The following comply:


void firstWordLowerCaseButInternalWordsCapitalized();

Rule 8: Do not include any underscore in name except after variables prefix.
Description

Apply to class, method, and variables.

Justification

This rule exists to distinguish a variables prefix from the first word in the variables name.

Example

The following comply:


//Class name
class GraduatedStudent
{
};
//Global variable
void PerformAction();
//Member variable
int m_maxItem;

TMA Confidential

TMA Solutions, 2004

Page 17 of 79

TMA Training Center


Issue Date: Apr 12, 06

Code: SW-GU-003
Version: 1.0

C/C++ Coding Guideline

The following do not comply:


//Class name
class Graduated_Student
{
};
//Global variable
void Perform_Action();
//Member variable
int m_max_Item;

Rule 9: Always make all letters of name uppercase.


Description

Apply to struct, union and constant.

Justification

This rule is to distinguish struct and union name from class name and constant name from
variable name.

Example

The following comply:


struct PERSON
{
};
union UNKNOW
{
};
const unsigned int VS_ERROR_INVALID_PARAMETER =

0;

The following do not comply:


struct Person
{
};
union Unknow
{
};
const unsigned int Vs_Error_Invalid_Parameter =

0;

Rule 10: Always make a combination of plane words by using underscore ( _ ).


Description

Apply to struct, union and constant.

Justification

This rule is to distinguish struct and union name from class name and constant name from
others, especially to make struct, union, and constant easy to see.

Example

The following comply:


struct VS_ERROR_CODE
{
};
union UNKNOW_TYPE
{
};
const unsigned int VS_ERROR_INVALID_PARAMETER

TMA Confidential

TMA Solutions, 2004

0;

Page 18 of 79

TMA Training Center


Issue Date: Apr 12, 06

Code: SW-GU-003
Version: 1.0

C/C++ Coding Guideline

The following do not comply:


struct Person
{
};
union UNKNOWTYPE
{
};
const unsigned int VS_ERROR_INVALIDPARAMETER

0;

Rule 11: Do not pluralize enumerated type name.


Description

Apply to enum.

Justification

Enumerated types define a single concept, so do not pluralize the types variable name
because plural names mean multiple concepts. Built-in types (like int and char) are not
pluralized, so enumerated types should not be different.

Example

The following comply:


enum PrimaryColor
{
};

The following do not comply:


enum PromaryColors
{
};

// should not use pluralized name

Rule 12: Never use number as word.


Description

Apply to class, struct, union, enum, method, variable, method argument, constant, and
namespace.

Justification

Using numbers as words makes confusing because it is too difficult to understand source
code.

Example

The following comply:


const unsigned int TRANSMIT_TO_SERVER = 2;

The following do not comply:


const unsigned int TRANSMIT_2_SERVER = 2;

Rule 13: Always make sure that argument names and its purposes are the same.
Description

Apply to method argument list.

Justification

This makes it is easier to understand how a function works. A user could be able to tell what
the arguments are and how the arguments are used without looking at the functions
definition.

TMA Confidential

TMA Solutions, 2004

Page 19 of 79

TMA Training Center


Issue Date: Apr 12, 06
Example

C/C++ Coding Guideline

Code: SW-GU-003
Version: 1.0

The following comply:


//File Car.h
class Car
{
public:
void Copy(Car *p_destination, Car *p_source);
}
//File Car.cpp
#include Car.h
Car::Copy(Car *p_destination, Car *p_source)
{
}

The following do not comply:


//File Car.h
class Car
{
public:
void Copy(Car *p_destination, Car *p_source);
}
//File Car.cpp
#include Car.h;
Car::Copy(Car *p_source, Car *p_destination)
{
// the order of arguments should be the same as prototype of method
}

Note: Even though Car::Copy(Car * p_source, Car * p_destination) is implemented correctly


this inverse arguments cant be acceptable.
The following also do not comply:
//File Car.h
class Car
{
public:
// Copy p_obj1 to p_obj2
void Copy(Car *p_obj2, Car *p_obj1);
}

Note: Should make clear p_obj2 is destination and p_obj1 is source.

Rule 14: Always name header and implement files the same as class name.
Description

Apply to class only.

Justification

Following this rule, it helps to browse class under ClassView and FileView modes
synchronizedly in Visual C++ environment. When using class, its clear and lucid to include
header file as well as to declare object of class.

Example

The following comply:


class StudentForm : public CDialog
{
}

TMA Confidential

TMA Solutions, 2004

Page 20 of 79

TMA Training Center


Issue Date: Apr 12, 06

C/C++ Coding Guideline

Code: SW-GU-003
Version: 1.0

// Above class name is StudentFrom


// Header file should be StudentFrom.h
// Implement file should be StudentForm.cpp

5. FORMAT CONVENTION
Rules in this section ensure that software is formatted in a consistent manner. Studies have shown that
developers have strong expectations about what software should look like. If there is no standard format for
software, then source code looks untidy. So format convention is born. The following are rules talking about
format.
Rule 1: Always indent new scope with two additional spaces.
Description

Apply to all objects.

Justification

This rule exists for consistency and readability. Two spaces are enough so that new scope is
recognized. With two spaces, there is more room on the line with 80 characters.

Example

The following comply:


class Vehicle
{
public:
void Drive();
protected:
void Park();
private:
void Steal();
}
void ArbitraryClass::PerformAction()
{
int numItem = 0;
}

The following do not comply:


class Vehicle
{
public: // should indent 2 more spaces
void Drive();
protected:
void Park();//should indent 2 spaces only
private:
void Steal();//should indent 2 more spaces
}
void ArbitraryClass::PerformAction()
{
int numItem = 0; //4 spaces - should indent 2 spaces only

TMA Confidential

TMA Solutions, 2004

Page 21 of 79

TMA Training Center


Issue Date: Apr 12, 06

C/C++ Coding Guideline

Code: SW-GU-003
Version: 1.0

Rule 2: Do not allow line to exceed 80 characters.


Description

Apply to all objects.

Justification

This rule makes easy to read a hard copy of software and easy to view in code review
meeting.

Example

If (A)
{
. // the length of line should be less than 80 chars
}

Rule 3: Always use space instead of tab.


Description

Apply to all objects.

Justification

Tab does not have the same interpretation in all cases; space does. For example, if software
uses tabs and is formatted to look good in one text editor, there is no
guarantee that the software will look good in a different text editor.
Note: With VC++ tool, we can configure this function through TOOL/OPTIONS/TAB, then
check Insert spaces.

Example

N/A this rule.

Rule 4: Do not code more than one statement per line.


Description

Apply to all object.

Justification

This helps readability.

Example

The following comply:


int numLongans; // maximum quantity of longans.
int numMangoes; // maximum quantity of mangos.
numLongans = numPears;
numMangoes = numPears;

The following do not comply:


int numLongans, numMangoes; // should break into 2 declaration lines
numLongans = numMangoes = numPears; //should do 2 actions on 2 lines
numLongans = numPears; numMangoes = numPears;
//should follow one end-command semicolon per one line.

TMA Confidential

TMA Solutions, 2004

Page 22 of 79

TMA Training Center


Issue Date: Apr 12, 06

C/C++ Coding Guideline

Code: SW-GU-003
Version: 1.0

Rule 5: Always add one more empty line between each section.
Description

Apply to all objects.

Justification

This make us easy to distinguish every sections and to read when reviewing, fixing and so
on.

Example

The following comply:


void ArbitraryClass::PerformAction()
{
// This is to execute main M1 system
PerformActionM1();
// This is to execute survivable cabinet system
PerformActionSurvivableCabinet();
//This is to execute media gateway system.
PerformActionMediaGetway();
//This is to.
}

The following do not comply:


void ArbitraryClass::PerformAction()
{
//This is to execute main M1 system
PerformActionM1();
//This is to execute survivable cabinet system
PerformActionSurvivableCabinet();
//This is to execute media gateway system.
PerformActionMediaGetway();
//This is to.
}

The following comply:


class Vehicle
{
public:
void Drive();
protected:
void Park();
private:
void Steal();
}

The following do not comply:


class Vehicle
{
public:
void Drive();
protected: //should add one empty line above this line
void Park();
private://should add one empty line above this line

TMA Confidential

TMA Solutions, 2004

Page 23 of 79

TMA Training Center


Issue Date: Apr 12, 06

C/C++ Coding Guideline

Code: SW-GU-003
Version: 1.0

void Steal();
}

Rule 6: Always make level alignment of every code section.


Description

Apply to all objects.

Justification

This rule is to help readability of software.

Example

The following comply:


void ArbitraryClass::PerformAction()
{
// This is to execute main M1 system
if (A)
{
if(A1)
{
for (int i = 0; i < MAX_ITEMS; i++)
{
//Do action here
}
}
else
{
//Do other action
}
}
//This is to.
}

The following do not comply:


void ArbitraryClass::PerformAction()
{
//This is to execute main M1 system
if (A)
{
if(A1) //should level alignment from here
{
for (int i = 0; i < MAX_ITEMS; i++)
{
//Do action here
}
}
else
{
//Do other action
}
}
//This is to.
}

Rule 7: Always put pair of braces around statement on new line even single line of code.
Description

Apply to all objects.

TMA Confidential

TMA Solutions, 2004

Page 24 of 79

TMA Training Center


Issue Date: Apr 12, 06

C/C++ Coding Guideline

Code: SW-GU-003
Version: 1.0

Justification

If braces are not placed where they are optional, then they must be added. Because the
software may become more complicated in the future. This is error-prone and can lead to
difficult problems while developing or fixing. It is less error-prone to always include the
braces.

Example

The following comply:


if (m_isError)
{
AfxMessageBox(ERROR_LEVEL1_MSG);
}
PerformNextAction();

The following do not comply:


if (m_isError)
AfxMessageBox(ERROR_LEVEL1_MSG);
PerformNextAction();

The following also do not comply:


if (m_isError) {
AfxMessageBox(ERROR_LEVEL1_MSG);
}
if (m_isError) AfxMessageBox(ERROR_LEVEL1_MSG);
if (m_isError)
{
AfxMessageBox(ERROR_LEVEL1_MSG);
}

The following comply:


struct PERSON
{
int age;
float weight;
}
enum COLOR
{
red,
green,
blue
}

The following do not comply:


struct PERSON{
int age;
float weight;
}
enum COLOR
{
red,
green,
blue}

TMA Confidential

TMA Solutions, 2004

Page 25 of 79

TMA Training Center


Issue Date: Apr 12, 06

C/C++ Coding Guideline

Code: SW-GU-003
Version: 1.0

6. CONSTANT CONVENTION
Please refer to rule #12 in section Naming Convention for more information.
Rule 1: Do not use #define to create the constant.
Description
Justification

Apply to constant.
(Refer to Effective C/C++)
When a constant is created using #define, the constants name is replaced by the
preprocessor; it is never seen by the compiler. This leads to confusing compiler error
messages that refer to the value instead of the name and causes problems for a symbolic
debugger. In addition, you can not use the & operator to get the address of
a constant created by using #define.
Define a constant using const does not have any of the above problems.

Example

The following comply:


const unsigned int MAX_ITEMS = 10;
The following do not comply:
#define MAX_ITEMS (10);
#define ASPECT_RATIO 1.653

The symbolic name ASPECT_RATIO may never be seen by compilers; it may


be removed by the preprocessor before the source code ever gets to a
compiler. As a result, the name ASPECT_RATIO may not get entered into the
symbol table. This can be confusing if you get an error during compilation
involving the use of the constant, because the error message may refer to
1.653, not ASPECT_RATIO. If ASPECT_RATIO was defined in a header file you
didn't write, you'd then have no idea where that 1.653 came from, and you'd
probably waste time tracking it down. This problem can also crop up in a
symbolic debugger, because, again, the name you're programming with may
not be in the symbol table. (Refer to Effective C/C++)

Rule 2: Do not use #define to create method-like macros.


Description

Apply to constant.

(Refer to Effective C/C++)


Justification

Method-like macros have all the disadvantages described in the justification of Rule Do not
use #define to create constant.
An additional disadvantage of function-like macros is the danger involved with passing in
expressions that have side effects. Methods(possibly created by using templates) can be just
as flexible as macros and have none of the disadvantages of macros.

TMA Confidential

TMA Solutions, 2004

Page 26 of 79

TMA Training Center


Issue Date: Apr 12, 06
Example

C/C++ Coding Guideline

Code: SW-GU-003
Version: 1.0

The following does not comply:


#define MAX(a,b) (((a) > (b) ? (a) : (b))
int ArbitraryClass::PerformAction()
{
unsigned int numApples = 10;
unsigned int numOranges = 5;
int maxNumFruit = MAX(++numApples, numOranges);
}

After maxNumFruit is initialized, numApples has been incremented twice (once when
evaluating the condition and once when returning a value). This is probably not what was
intended.
The following comply:
template <class T> const T& max( const T& value1, const T& value2 )
{
T maxValue = 0;
if( value1 < value2 )
{
maxValue = value2;
}
else
{
maxValue = value1;
}
return maxValue;
}

Rule 3: Always declare the constant when possible.


Description

Apply to local variable, method parameter, class function, class member variable.

Justification

Making items constant avoids inadvertent changing of something that was not meant to be
changed. This makes software more readable and may help the compiler as well.

Example

The following do not comply:


void ArbitraryClass::PerformAction( int num )
{
bool isOdd = false;
isOdd = IsNumOdd(num);
if( isOdd )
{
bool isPrime = false;
isPrime = IsNumPrime( num );
// use isPrime
}
}

The function parameter and each local variable should be constants.


The following comply:

TMA Confidential

TMA Solutions, 2004

Page 27 of 79

TMA Training Center


Issue Date: Apr 12, 06

C/C++ Coding Guideline

Code: SW-GU-003
Version: 1.0

void ArbitraryClass::PerformAction( const int num )


{
const bool isOdd = IsNumOdd( num );
if( isOdd )
{
const bool isPrime = IsNumPrime( num );
}
// use isPrime
}

!! Consider a class that stores information about a book. Each book has a title, an author, and
a publisher. For any given book, this information does not change, so
the members should be constant.
The following do not comply:
class Book
{
public:
Book(CString &r_title, CString &r_author, CString &r_publisher);
private:
CString m_title; //should be constant
CString m_author; //should be constant
CString m_publisher; //should be constant
};

The following comply:


class Book
{
public:
Book(const CString &r_title, const CString &r_author,
const CString &r_publisher);
private:
const CString m_title;
const CString m_author;
const CString m_publisher;
};

!! Consider a class that has a get and set functions.


The following do not comply:
class ArbitraryClass
{
public:
void SetValue(int value); //value can be constant
int GetValue(); //should be constant
private:
int m_value;
};

GetValue does not modify any members of the class. Therefore, this function can be made
constant.

TMA Confidential

TMA Solutions, 2004

Page 28 of 79

TMA Training Center


Issue Date: Apr 12, 06

C/C++ Coding Guideline

Code: SW-GU-003
Version: 1.0

The following comply:


class ArbitraryClass
{
public:
void SetValue(const int value);
int GetValue() const;
private:
int m_value;
};

Using const in this way promises the compiler that the function does not modify any of the
class members.

Rule 4: Always define constant for literal except 0, 1 and true, false.
Description

Apply to literal number, character and string.

Justification

Using constants instead of literals has the following advantages:


Changes can be made more reliably and easily. For example, suppose the maximum
number of items is 20. What happens when the maximum number of items becomes 40? If
the value 20 is used throughout the software, each occurrence of 20 must be replaced with
40. This is error-prone because one of the 20s might be overlooked or a 20 that doesnt
represent the maximum number of items might be inadvertently changed to a 40. If a named
constant is used, only the constants value needs to change.
Software is easier to understand.

Example

The following does not comply:


for (int i = 7; i <= 83; i++)
{
// do something
}

It is impossible to know what this software does without comments. If the software is
written with named constants, it is much easier to read.
The following complies:
const unsigned int BOTTOM_VALUE = 7;
const unsigned int TOP_VALUE = 83;
for (int i = BOTTOM_VALUE; i <= TOP_VALUE; i++)
{
// do something
}

7. OPERATOR CONVENTION

TMA Confidential

TMA Solutions, 2004

Page 29 of 79

TMA Training Center


Issue Date: Apr 12, 06

C/C++ Coding Guideline

Code: SW-GU-003
Version: 1.0

Rule 1: Do not add a white space between unary operator and its operand.
Description

Apply to unary operator only.

Justification

This rule exists to make software is easy to read.

Example
Unary operators

*, &, !, ~, ++, --, []

The following comply:


int maxSignalLength = 10;
int *p_maxSignalLength = 0;
p_maxSignalLength = &maxSignalLength;
if (!mb_isMainSystem)
{
oldValue = ~newValue;
newValue++;
--oldValue;
}
int *p_systemList = new int(MAX_SYSTEM);
delete []p_ systemList;

The following do not comply:


int maxSignalLength = 10;
int* p_maxSignalLength; //should be no space between * and variable name
p_maxSignalLength = & maxSignalLength;
//should be no space between & and variable name
if (! mb_isMainSystem) // should be no space between ! and variable name
{
oldValue = ~ newValue;//should be no space between ~ and variable name
newValue ++;//should be no space between ++ and variable name
-- oldValue; //should be no space between -- and variable name
}
int * p_systemList = new int(MAX_SYSTEM);
// should be no space between * and variable name
delete[] p_ systemList;
// should be no space between [] and variable name

Rule 2: Always add a white space before and after to operators.


Description

Apply to assignment operator, logical operator, arithmetic operator, bitwise operator, and
relational and equality operator.

Justification

This rule exists to make software is easy to read.

Example
Assignment operators
Logical operators
Arithmetic operators
Bitwise operators
Relational and equality operators
Shift operators

TMA Confidential

=, +=, -=, *=, /=, %=, <<=, >>=, &=, ^=, |=


&&, ||
+, -, *, /, %
&, ^, |
==, <, <=, >, >=, !=
>>, <<

TMA Solutions, 2004

Page 30 of 79

TMA Training Center


Issue Date: Apr 12, 06

C/C++ Coding Guideline

Code: SW-GU-003
Version: 1.0

The following comply:


int numItem = GetItem();
if ((numItem > MAX_ITEM) && (systemType == SYSTEM_TYPE))
{
int tempValue = (oldValue << newValue);
}

The following do not comply:


int numItem = GetItem();
if ((numItem>MAX_ITEM)&&(systemType==SYSTEM_TYPE))
{
int tempValue=(oldValue<<newValue);
}

Rule 3: Do not use ? operator.


Description

Do not apply to member initialization lists.

Justification

The ? operator is a short form if statement that can be very difficult to read. A compiler
creates identical software for an if statement as it does for the ? operator. Therefore, use an if
statement instead.

Example

The following do not comply:


int num = (value1 <= 10) ? ( (value2 >= 5) ? 5 : 10 ) :
( (value1 <= 20) ? 10 : ( (value1 <= 30) ? 20 : 30 ) );
// should use if-else

The following comply:


int num = 0;
if (value1 <= 10)
{
if (value2 >= 5)
{
num = 5;
}
else
{
num = 10;
}
}
else if (value1 <= 20)
{
num = 10;
}
else if (value1 <= 30)
{
num = 20;
}
else
{
num = 30;
}

The following also comply: (initialization list)

TMA Confidential

TMA Solutions, 2004

Page 31 of 79

TMA Training Center


Issue Date: Apr 12, 06

C/C++ Coding Guideline

Code: SW-GU-003
Version: 1.0

ArbitraryClass::ArbitraryClass( const int value ) :


m_value( ( value <= someSpecialValue ) ? value1 : value2 )
{
}

8. CONTROL FLOW CONVENTION


Please refer to rule #7 in section Format Convention for more information.
Rule 1: Do not change a loop variable inside for loop block.
Description

Apply to for loop only.

Justification

When you write a for loop, it is highly confusing and error-prone to change the loop variable
within the loop body rather than inside the expression executed after each iteration.

Example

The following comply:


for (int i = 0, int j = 8; i < MAX_SIZE; i++)
{
// Value of i is never chagned here
}

The following do not comply:


for (int i = 0, int j = 8; i < MAX_SIZE; i++)
{
// Somehow value of i is changed here
}

Rule 2: Always add default for switch statement.


Description

Apply to switch-case statement only.

Justification

This leads to more robust software.

Example

The following comply:


switch (A)
{
case 1:
// do this;
break;
case 2:
// do that;
break;
default:
// do other things;
}

The following do not comply:


switch (A)

TMA Confidential

TMA Solutions, 2004

Page 32 of 79

TMA Training Center


Issue Date: Apr 12, 06

C/C++ Coding Guideline

Code: SW-GU-003
Version: 1.0

{
case 1:
// do this;
break;
case 2:
// do that;
break;
}

Rule 3: Always follow the sample of statements as following form.


Description

Apply to try-catch, if-else, for, while, do-while, and switch.

Justification

This rule is to help readability.


- Add one white space after statement.
- Add one white space after comma, semicolon.
- Do not add a white space between unary operator and its operand.
- Add a white space before and after to operators except unary operators.

Example

if else statement:
if (A == B)
{
// do something here
}
if (A == B)
{
// do this
}
else
{
// do that
}

for statement:
for (int i = 0; i < MAX_ITEM; i++)
{
// do something here
}
for (int i = 0, int j = MAX_LENGTH - 1; i >= j; i++, j--)
{
// do something here
}

while statement:
while (A == B)
{
// do something here
}

do-while statement:
do

TMA Confidential

TMA Solutions, 2004

Page 33 of 79

TMA Training Center


Issue Date: Apr 12, 06

C/C++ Coding Guideline

Code: SW-GU-003
Version: 1.0

{
// do something here
}
while (A == B);

switch-case statement:
switch (A)
{
case 1:
{
// block of commands;
break;
}
case 2:
// single command;
break;
default:
// do other things;
}

try-catch statement:
try
{
// Write the header file
file.Write((LPSTR)&r_bmpfileHeader, sizeof(BITMAPFILEHEADER));
//Write the DIB header and the bits
file.WriteHuge(lp_bi, dw_dibSize);
}
catch (CFileException* e)
{
::GlobalUnlock((HGLOBAL), hDib);
throw;
}

Rule 4: Do not use goto keyword to replace control flow statements or other purposes.
Description

Apply to all situations.

Justification

This leads to more robust software.

Example

The following comply:


do
{
// do something here
}
while (TRUE == IsRepeated());

The following do not comply:


TheLable:
// do something here
if (TRUE == IsRepeated())

TMA Confidential

TMA Solutions, 2004

Page 34 of 79

TMA Training Center


Issue Date: Apr 12, 06

C/C++ Coding Guideline

Code: SW-GU-003
Version: 1.0

{
goto TheLable;
}

The following also do not comply:


for (int p = 0; p < NUM_PATHS; ++p)
{
numFiles = FillArray( pFileArray, pszFNames )
for (int i = 0; i < numFiles; ++i)
{
pFileArray[i] = fopen( pszFNames[i], "r" );
if (NULL == pFileArray[i])
{
goto FileOpenError;
}
// Process the files that were opened.
}
}
FileOpenError:
cerr << "Fatal file open error. Processing interrupted.\n" );
The following comply:
for (int p = 0; p < NUM_PATHS; ++p)
{
numFiles = FillArray( pFileArray, pszFNames )
for (int i = 0; i < numFiles; ++i)
{
pFileArray[i] = fopen( pszFNames[i], "r" );
if (NULL == pFileArray[i])
{
break;
}
// Process the files that were opened.
}
if (i<numFiles)
{
cerr << "Fatal file open error. Processing interrupted.\n" );
break;
}
}

9. EXPRESSION CONVENTION
Rules in this section ensure that expression in software is clear and neat. If you browse any fragment of code,
then you can be easy to recognize the processing order of expression. Following these rules, unexpected error
will not occur as error-prone. The following are rules talking about expression.
Please refer to rules in section Format, Variable and Operator Conventions for more information.
Rule 1: Always avoid embedding the assignment within another expression.
Description

Apply to all expressions.

TMA Confidential

TMA Solutions, 2004

Page 35 of 79

TMA Training Center


Issue Date: Apr 12, 06

C/C++ Coding Guideline

Code: SW-GU-003
Version: 1.0

Justification

This rule exists to make clear source code. Its easy for developer, reviewer, and fixer to
recognize what fragment of code does.

Example

The following comply:


c = getchar();
while (EOF != c)
{
// do something here
c = getchar();
}

The following do not comply:


while (EOF != (c = getchar()))
{
// do something here
}

Rule 2: Should put the constant, TRUE/FALSE, .. on the left of comparison expression.
Description

Apply to all expressions.

Justification

This rule helps developer, reviewer, and fixer to debug software easily.

Example

The following comply:


FILE *f;
f = fopen(datafile, r);
if (0 != f)
{
m_numOpenFile++;
}
else
{
//one error occurs while opening file.
}

The following do not comply:


FILE *f;
f = fopen(datafile, r);
if (f != 0) //should put 0 on the left
{
m_numOpenFile++;
}
else
{
//one error occurs while opening file.
}

The following comply:


if (MAX_NUM_OPEN_FILE < m_numOpenFile)
{
//totally open file is over MAX_NUM_OPEN_FILE
}

TMA Confidential

TMA Solutions, 2004

Page 36 of 79

TMA Training Center


Issue Date: Apr 12, 06

C/C++ Coding Guideline

Code: SW-GU-003
Version: 1.0

The following do not comply:


if (m_numOpenFile > MAX_NUM_OPEN_FILE)
//should put MAX_NUM_OPEN_FILE on the left
{
//totally open file is over MAX_NUM_OPEN_FILE
}

The following comply:


void ArbitraryClass::PerformAction()
{
if (TRUE == IsTestStarted())
{
// the test is started
}
else
{
// the test is not started
}
}

The following do not comply:


void ArbitraryClass::PerformAction()
{
if (IsTestStarted() == TRUE) ) //should put TRUE on the left
{
// the test is started
}
else
{
// the test is not started
}
}

Rule 3: Do not use integer variable as bool variable in conditional expression.


Description

Apply to all expression.

Justification

Following this rule, software will look neat. And no error-prone occurs if possible. Because
integer variable will be changed by float variable somehow in the future.

Example

The following comply:


int isActive = 0;
if (0 == isActive)
{
//do this
}
else
{
//do that
}

The following do not comply(even no error):


int isActive = 0;

TMA Confidential

TMA Solutions, 2004

Page 37 of 79

TMA Training Center


Issue Date: Apr 12, 06

C/C++ Coding Guideline

Code: SW-GU-003
Version: 1.0

if (false == isActive) // should be 0 == isActive


{
//do this
}
else
{
//do that
}

The following comply:


bool isActive = false;
if (false == isActive)
{
//do this
}
else
{
//do that
}

The following also do not comply:


int isActive = 0;
if (!isActive)
{
//do this
}
else
{
//do that
}

Rule 4: Always include parenthesis in expression if possible.


Description

Apply to all expression.

Justification

This rule is to make clear order processing of expression.

Example

The following comply:


if (x > (y+1))
{
}
x = a + (b * c);

The following do not comply:


if (x > y+1)
{
}
x = a + b * c;

Rule 5: Always separate operators groups from parenthesis.


Description

Apply to all expression.

TMA Confidential

TMA Solutions, 2004

Page 38 of 79

TMA Training Center


Issue Date: Apr 12, 06

C/C++ Coding Guideline

Code: SW-GU-003
Version: 1.0

Justification

This rule is to make clear order processing of expression. If the rule is used, then software
look neat and easy to compute manually as needed.

Example

The following comply:


total = ((a + b - c) * MAX_ELEMENT) - (x + y - z);

The following do not comply:


total = (a + b - c ) * MAX_ELEMENT - x - y + z;

10. POINTER AND MEMORY MANAGEMENT


CONVENTION
Memory usage in C++ is as the sea come to land:
A tide rolls in, and sweeps out again, leaving only puddles and stranded fish.
At intervals, a wave crashes ashore; but the ripples never cease.
The extensibility of C++ can increase substantially the number and kinds of errors that can occur. The feature,
exception handling, here enable programmer s to write clearer, more robust and more fault-tolerant programs.
Rule 1: Do not use malloc, free, calloc, realloc, and ... operators from standard C.
Description

Apply to dynamic memory allocation.

Justification

When you use new and delete instead of malloc and free, you are able to take advantage of
the class librarys memory-management debugging enhancements, which can be useful in
detecting memory leaks. When you build your program with the Release version of MFC,
the standard versions of the new and delete operators provide an efficient way to allocate
and deallocate memory.
There is a note important for us to take a look. The following information is extracted from
Memory Management Topics.
! Mixing the new and delete operators with the resizable memory-allocation functions on the
same memory block will result in corrupted memory in the Debug version of MFC. You
should not use realloc on a memory block allocated with new. Likewise, you should not
allocate a memory block with the new operator and delete it with free, or use the delete
operator on a block of memory allocated with malloc.

Example

The following comply:


char *path;
// Allocate space for a path name
path = new char[MAX_PATH];
if (0 == path)
{
cout << "Insufficient memory available\n";
}

TMA Confidential

TMA Solutions, 2004

Page 39 of 79

TMA Training Center


Issue Date: Apr 12, 06

C/C++ Coding Guideline

Code: SW-GU-003
Version: 1.0

else
{
cout << "Memory space allocated for path name\n" ;
delete []path;
cout << "Memory deleted\n";
}

The following do not comply:


char *path;
// Allocate space for a path name
path = (char *)malloc(MAX_PATH);
if (0 == path)
{
cout << "Insufficient memory available\n";
}
else
{
cout << "Memory space allocated for path name\n" ;
delete []path;
cout << "Memory freed\n";
}

Rule 2: Always use new and delete operators consistently and accurately.
Description

Apply to dynamic memory allocation.

Justification

This rule exists because failure to release all free store memory that you allocate with
operator new is called memory leak. Memory leak is difficult to find, so the best way to
avoid them and go the following.
! When you allocate an array of objects with operator new, use the [] notation with operator
delete to release the array. Programs with loops that use operator new to allocate objects
one at a time should have corresponding loops to release each object with operator delete
without [].

Example

The following comply:


int *p_numItems = new int[MAX_ITEMS];
delete []p_numItems;

The following do not comply:


int *p_numItems = new int[MAX_ITEMS];
//Delete allocated pointer.
delete p_numItems;
//Another way.
for (int i = 0; i < MAX_ITEMS; i++)
{
delete p_numItems[i];
}

The following comply:

TMA Confidential

TMA Solutions, 2004

Page 40 of 79

TMA Training Center


Issue Date: Apr 12, 06

C/C++ Coding Guideline

Code: SW-GU-003
Version: 1.0

int *p_numItems[MAX_ITEMS];
// Allocate space for a list of items
for (int i = 0; i < MAX_ITEMS; i++)
{
p_numItems[i] = new int(0);
}
//Delete allocated pointer.
for (int i = 0; i < MAX_ITEMS; i++)
{
delete p_numItems[i];
}

The following do not comply:


int *p_numItems[MAX_ITEMS];
// Allocate space for a list of items
for (int i = 0; i < MAX_ITEMS; i++)
{
p_numItems[i] = new int(0);
}
// Delete allocated pointer
delete []numItems;

Rule 3: Always check existence of pointer before using it.


Description

Apply to dynamic memory allocation.

Justification

This rule exists to make sure accessing to pointer is correct.

Example

The following comply:


int *p_size = new int[size];
if (0 != p_size)
{
//Do something with p_size
delete []p_size;
}

The following do not comply:


int *p_size = new int[size];
// Do something with p_size
delete []p_size;

Rule 4: Should use 0 instead of NULL.


Description
Justification

Apply to pointer.
(Standard C)
Standard C++ type conversions allow 0 to be used as a constant of any pointer type. NULL
is macro which defines either as (void*) 0 or as 0 in standard C. If this definition remains in
C++, problems may rises. Because if NULL is defined as void*, then it can not be assigned
an arbitrary pointer without explicit type convention. For this reason, always compare a

TMA Confidential

TMA Solutions, 2004

Page 41 of 79

TMA Training Center


Issue Date: Apr 12, 06

C/C++ Coding Guideline

Code: SW-GU-003
Version: 1.0

pointer with 0 in order to meet standard conversion. This leads to fewer error-prone than
using any conceivable NULL macro.
Example

The following comply:


int *p_size = new int[size];
if (0 != p_size)
//Do something with p_size
delete []p_size;
}

The following do not comply:


int *p_size = new int[size];
if (NULL != p_size) //error sometimes
//Do something with p_size
delete []p_size;
}

The following also do not comply:


int *p_size = new int[size];
if (!p_size) //dont meet standard
//Do something with p_size
delete []p_size;
}

Rule 5: Should implement exception handling as needed.


Description

Apply to dynamic memory allocation.

Justification

1. Why we implement it when necessary? Because:


Exception can not be ignored.
2. Why we do not implement it? Because
Pay for space: program must do a fair amount of bookkeeping. At each point during
execution, they must be able to identify the objects that require destruction, if an exception is
thrown; they must take note of each entry to and exit from a try block; and for each try
block, they must keep track of the associated catch clauses and the type of exceptions those
clauses can handle. Code size is increased 5-10%
Pay for time: program must need time to keep these data structures updated at runtime.
Runtime of program is also about to go up 5-10%
Note: The cost of exception handling arises from try blocks, and you pay it whenever you
use one, whenever you decide you want to be able to catch exceptions. Different compilers
implement try blocks in different ways, so the cost varies from compiler to compiler. As a
rough estimate, expect your overall code size to increase by 5-10% and your runtime to go
up by similar amount if using try blocks.
How to write exception-safe software: We will sidestep many problems that commonly
arise when working with exceptions because of incomplete guide.

Example

The following do not comply:


int *pName = new int[MAX_LENGTH];

TMA Confidential

TMA Solutions, 2004

Page 42 of 79

TMA Training Center


Issue Date: Apr 12, 06

C/C++ Coding Guideline

Code: SW-GU-003
Version: 1.0

The following comply:


try
{
int *pName = new int[MAX_LENGTH];
}
catch()
{
delete []pName;
}

The following do not comply:


AbitraryObject *pObject = new ArbitraryObjet(); // Should catch memory
exception

The following comply:


AbitraryObject *pObject = 0;
try
{
pObject = new ArbitraryObjet();
}
catch()
{
delete pObject;
pObject = 0;
}

Rule 6: Should use exception handling instead of status value and error code.
Description

Apply to all variable types.

Justification

For error reporting, exception handling is a more powerful technique than returning status
values and error codes. It allows to separate code that handles errors from the ordinary flow
of control. Because an exception is an object, an arbitrary amount of error information can
be stored in an exception object; the more information that is available, the greater the
chance that the correct decision is made for how to handle the error. In certain cases,
exception handling can be localized to one function along a call chain; this implies that less
code needs to be written, and it is more legible.

Example

The following comply:


try
{
// ordinary flow of control
f();
g();
}
// handler for any kind of exception
catch(...)
{
// error handling
}

TMA Confidential

TMA Solutions, 2004

Page 43 of 79

TMA Training Center


Issue Date: Apr 12, 06

C/C++ Coding Guideline

Code: SW-GU-003
Version: 1.0

11.VARIABLE AND DATA TYPES CONVENTION


Variable is not dropped out. Yes, but you have to utilize its steps as much as possible. This section is to
improve ways of using varibale and data type as well.
Please refer to rules #2, #4, #5, #6, #7, #8 and #12 in section Naming Convention and rules in section Format
Convention for more information.
Rule 1: Should use unsigned data type when value can not be negative.
Description

Apply to all variable types.

Justification

This rule is to make software easier to understand.

Example

The following comply:


//This value is always positive
unsigned int m_numGoalsScored;

The following do not comply:


int m_numGoalsScored;

Rule 2: Do not have method and non-public variable members in a structure.


Description

Apply to structure.

Justification

Structures are only used to keep related information together. If a structure has userdefined functions or non-public members, it has more complicated behavior. Should be
a class. By the default, members of structure is public.

Example

The following comply:


struct PERSON
{
unsigned int id;
unsigned int age;
.
}

The following do not comply:


struct PERSON
{
unsigned int id;
unsigned int age;
.
private: //should not use this
bool sex;
int GetStatus();
}

TMA Confidential

TMA Solutions, 2004

Page 44 of 79

TMA Training Center


Issue Date: Apr 12, 06

C/C++ Coding Guideline

Code: SW-GU-003
Version: 1.0

Rule 3: Always postpone variable definition as long as possible.


Description

Apply to local variable.

Justification

This rule decreases a variables life span, which increases software readability. In addition, a
variables constructor is executed upon definition. If the variable is not used, executing the
constructor is unnecessary.

Example

The following comply:


for (int i = 0; i < MAX_LOOP_TIME; i++)
{
}

The following do not comply:


int i = 0;
for (i = 0; i < MAX_LOOP_TIME; i++)
{
}

The following comply:


void ClassA::ActionPerformed()
{
if (FALSE == IsActive())
{
//Do something here like warming,..
}
else
{
if (0 < GetCurrentStudentId())
{
int retValue = DoAction();
//Use retValue here
}
}
}

The following do not comply:


void ClassA::ActionPerformed()
{
int retValue; // in this outer scope retValue is not used,
// so delay to declare it as long as possible
if (FALSE == IsActive())
{
//Do something here like warming,..
}
else
{
if (0 < GetCurrentStudentId())
{
retValue = DoAction();
//Use retValue here
}
}
}

TMA Confidential

TMA Solutions, 2004

Page 45 of 79

TMA Training Center


Issue Date: Apr 12, 06

C/C++ Coding Guideline

Code: SW-GU-003
Version: 1.0

Note: Because retValue variable is used only in the nested if statement. So delaying to
declare this variable is for certain.
The following do not comply:
#include <Vertex.h>
BOOL Rectangle::Rotate()
{
Vertex vertex;
if (FALSE == IsValid() )
{
return FALSE;
}
// use vertex here
return TRUE;
}

The following comply:


#include <Vertex.h>
BOOL Rectangle::Rotate()
{
if (FALE == IsValid())
{
return FALSE;
}
Vertex vertex;
// use vertex here
return TRUE;
}

Note: If method IsValid() somehow returns FALSE, then it is unnecessary to destruct vertex
variable when this method returns.
Rule 4: Do not use the same variable name in outer and inner scopes.
Description

Apply to all variable types.

Justification

Following this rule software is neat otherwise the code would be very hard to understand;
and it would certainly be a major error-prone condition.

Example

The following do not comply:


int x = 1;
if (a == b)
{
int x; //
//do this
}
else
{
//do that
}
//do others

should differ from x


with x

with x
with x

The following comply:

TMA Confidential

TMA Solutions, 2004

Page 46 of 79

TMA Training Center


Issue Date: Apr 12, 06

C/C++ Coding Guideline

Code: SW-GU-003
Version: 1.0

int x = 1;
if (a == b)
{
int y;
//do this with y
}
else
{
//do this with x
}
//do others with x

Rule 5: Do not declare member variables as non-private.


Description

Apply to member variables of class.

Justification

Public member variables declaration violates encapsulation principles. Making variables


public gives up control over internal class structure.

Example

The following comply:


class Product
{
private:
double md_price;
}

The following do not comply:


class Product
{
public:
double md_price;
}

Please refer to rules #3, #4 in section Class Convention for more information.

12. METHOD CONVENTION


Please refer to rules #1, #3, #5, #8, #12, #13 and #14 in section Naming Convention and rules in section
Format Convention and rule #3 in section Constant Convention for more information.
Rule 1: Always order method arguments as follows: input, input and output, and output.
Description

Apply to method (from left to right).

Justification

Consistently ordering method arguments in this way makes it easier to read and understand
method.

Example

The following comply:


// This method is to get student name while passing to student id.
void GetStudentName(long studentId, char studentName[]);

TMA Confidential

TMA Solutions, 2004

Page 47 of 79

TMA Training Center


Issue Date: Apr 12, 06

C/C++ Coding Guideline

Code: SW-GU-003
Version: 1.0

The following do not comply:


// This method is to get student name while passing to student id.
void GetStudentName(char studentName[], long studentId);

Rule 2: Do not pass class and structure arguments by value.


Description

Apply to method.

Justification

Passing by value reduces performance. Because when by passing by value, method


arguments are copied to the stack via invocations of copy constructor. In addition, destructor
is invoked when exiting the method.
Instead of passing by value, pass by pointer or reference as method arguments because
when passing by pointer or reference, no new objects are created on the stack. Only pointer
or reference to the object is placed on the stack.

Example

The following comply:


void PerformAction (const ArbitraryClass &r_arbitraryClass);

The following do not comply:


void PerformAction (const ArbitraryClass arbitraryClass);

Rule 3: Always name method arguments.


Description

Apply method arguments.

Justification

Naming method arguments make it easier to understand the its purpose.

Example

The following comply:


CString GetName(int id );
CString Student::GetName(int id)
{
}

The following do not comply:


CString GetName(int);
CString Student::GetName(int)
{
}

Rule 4: Always place return statement at the last line of method.


Description

Dont apply this rule in case we need to check simple error condition at the beginning of the
method.

Justification

If this rule is applied, method implementation is clear and easy to understand which state is
met. Otherwise, it is too hard to understand how this method works and which things need
to be done before exiting the method.

Example

The following comply:

TMA Confidential

TMA Solutions, 2004

Page 48 of 79

TMA Training Center


Issue Date: Apr 12, 06

C/C++ Coding Guideline

Code: SW-GU-003
Version: 1.0

BOOL Student::DeleteStudent(unsigned int studentId)


{
BOOL retValue = FALSE;
if (TRUE == LockDatabase()) //Lock database before deleting
{
//Do something relating to this record such as update
//
if (TRUE == DeleteRecord(studentId))
{
retValue = TRUE;
}
UnLockDatabase();
}
return retValue;
}

The following do not comply:


BOOL Student::DeleteStudent(unsigned int studentId)
{
if (TRUE == LockDatabase()) //Lock database before deleting
{
//Do something relating to this record such as update
//
if (FALSE == DeleteRecord(studentId))
{
return false;
}
UnLockDatabase();
return true;
}
else
{
return false;
}
}

Note: Why the code above is not complied? The answer is it is too hard to know how this
method works while using a lot of return statements. But the most important thing is that
unexpected problem occurs when method DeleteRecord returns false value, because the
database is still locked.
Rule 5: Always specify return type explicitly even though default type is int.
Description

Apply to method.

Justification

Specifying a methods return type helps understanding and takes the decision away from the
compiler.

Example

The following comply:


int GetHeightInFeet();
int Student::GetHeightInFeet()
{
return mi_heightInFeet;

TMA Confidential

TMA Solutions, 2004

Page 49 of 79

TMA Training Center


Issue Date: Apr 12, 06

C/C++ Coding Guideline

Code: SW-GU-003
Version: 1.0

The following do not comply:


GetHeightInFeet(); // Should declare function return clearly.
int Student::GetHeightInFeet()
{
return mi_heightInFeet;
}

Rule 6: Do not return pointer and reference to local variable.


Description

Apply to method.

Justification

This is a dangerous practice because non-static local variables go out of scope as soon as the
functions execution ends. The memory used for such variables can then be reused any time
after.

Example

The following do not comply:


int* AbitraryClass::PerformActionA()
{
int value = GetValue();
return &value;
}
int& AbitraryClass::PerformActionB()
{
int value = GetValue();
return value;
}

The following comply:


int* AbitraryClass::PerformActionA()
{
int *p_value = new int(GetValue());
return value;
}
void AbitraryClass::PerformActionA(int &p_outValue)
{
p_outValue = GetValue();
}

Rule 7: Always call static method using CLASSNAME::[static method] format.


Description

Apply to static method of different class.

Justification

Calling static class method from another class without using the scope operator makes it
appear that an object is subject to change. Using the scope operator makes it obvious that no
object is changing.

Example

Given the following class named A


//File A.h
static int s_maxAge;

TMA Confidential

TMA Solutions, 2004

Page 50 of 79

TMA Training Center


Issue Date: Apr 12, 06

C/C++ Coding Guideline

Code: SW-GU-003
Version: 1.0

class A
{
public:
static void SetMaxAge(int maxAge);
void PrintMaxAge();
};
//File A.cpp
void A::SetMaxAge(int maxAge)
{
s_maxAge = maxAge;
}
void PrintMaxAge()
{
cout << s_maxAge << endl;
}

The following comply:


//File B.cpp;
#include <A.h>
void B::PerformAction()
{
A::SetMaxAge(100);
A a;
a. PrintMaxAge(); // 100 is printed out
}

The following do not comply:


//File B.cpp;
#include <A.h>
void B::PerformAction()
{
A a;
a.SetMaxAge(100); //dont comply because of static method
A a1;
a1.PrintMaxAge(); //100 is printed out
}

Note: In C++, when modifying a data member in a class declaration, the static keyword
specifies that one copy of the member is shared by all the instances of the class.
Rule 8: Do not use inline method when they are not really needed
Description

Apply to inline method only if performance is your absolute top priority and a function is
very simple.

Justification

A function is generally made inline to improve performance. However, there is no need to


consider inlining a function until it is proven that the overhead associated with calling the
function is the source of poor performance. In addition, an inline function increases the size
of object files.

Example

The following comply:


//ApplicationProfile.h
class ApplicationProfile

TMA Confidential

TMA Solutions, 2004

Page 51 of 79

TMA Training Center


Issue Date: Apr 12, 06

C/C++ Coding Guideline

Code: SW-GU-003
Version: 1.0

{
public:
inline BOOL IsDirty();
private:
BOOL mb_dirty;
}
//File ApplicationProfile IL.h
inline BOOL ApplicationProfile::IsDirty()
{
return mb_dirty;
}

The following do not comply:


//ApplicationProfile.h
class ApplicationProfile
{
public:
inline BOOL IsDirty();
private:
BOOL mb_dirty;
}
//File ApplicationProfile IL.h
inline BOOL ApplicationProfile::IsDirty()
{
// do a lot of things may cause bad performance here
return mb_dirty;
}

Note: Please refer to rule #3, #4 in section #5 for more information.


Rule 9: Do not create method that have more than seven arguments.
Description

Apply to method argument

Justification

Studies have shown that humans have trouble comprehending more than seven discrete
pieces of information at once. Therefore, method that accepts more than seven arguments is
difficult to understand. If a methods requires more than seven
arguments, then this can indicate poor design. Consider revisiting your design or grouping
related arguments into a structure.

Example

The following comply:


struct
{
UINT
UINT
UINT
UINT
UINT
UINT
UINT

TMA Confidential

STUDENT_MARK
maths;
physics;
chemistry;
biologic;
english;
gym;
philosophy;

TMA Solutions, 2004

Page 52 of 79

TMA Training Center


Issue Date: Apr 12, 06

C/C++ Coding Guideline

Code: SW-GU-003
Version: 1.0

};
void InputStudentMark(UINT studentId, STUDENT_MARK &r_studentMark);

The following do not comply:


void InputStudentMark(UINT studentId, UINT & r_maths, UINT & r_physics,
UINT & r_chemistry, UINT & r_biologic, UINT & r_english,
UINT & r_gym, UINT & r_philosophy);

Rule 10: Always include a white space after a comma.


Description

Apply to for statement and arguments list of method.

Justification

This helps readability.

Example

The following comply:


int ArbitraryClass::PerformAction(int argrument, int argument1);
int result = PerformAction(5, 10);
for (int i = 0, int j = size 1; i >= j; i++, j--)
{
}

The following do not comply:


int ArbitraryClass::PerformAction(int argrument,int argument1);
int result = PerformAction(5,10);
for (int i = 0,int j = size 1; i >= j; i++,j--)
{
}

Rule 11: Do not add a white space after method name when calling method.
Description

Apply to method.

Justification

This is to distinguish method call from others.

Example

The following comply:


CString studentState = GetState();

The following do not comply:


CString studentState = GetState ();

Rule 12: Do not use unspecified arguments ().


Description

Apply to method.
Please refer to rule #3 in this section for more information.

Justification

One of the main advantages of C++ is that it is a strongly-typed language. Using unspecified
arguments automatically loses this advantage.
If the number of arguments is known but the exact type of arguments is unknown, use

TMA Confidential

TMA Solutions, 2004

Page 53 of 79

TMA Training Center


Issue Date: Apr 12, 06

Code: SW-GU-003
Version: 1.0

C/C++ Coding Guideline

overloaded functions or use a pointer to a base class for each argument. If these are not
possible, use a void * for each argument.
If the type of arguments is known but the exact number of arguments is unknown use a
vector (from the standard template library) argument to pass in the values.
Example

The following do not comply:


void ArbitraryClass::ActionPerformed();

The following comply:


void
void
void
void

ArbitraryClass::ActionPerformed(int
ArbitraryClass::ActionPerformed(int
ArbitraryClass::ActionPerformed(int
ArbitraryClass::ActionPerformed(int
int arg4);

arg1);
arg1, int arg2);
arg1, int arg2, int arg3);
arg1, int arg2, int arg3,

If the function accepts one hundred to five hundred int parameters, this approach becomes
too tedious. In this case, we can use a vector from the standard template library (STL), which
has a built-in size:
The following also comply:
void ArbitraryClass::ActionPerformed(vector<int>& argList)
{
//use argList.size();
}

13. CLASS CONVENTION


Please refer to rule #14 in section Naming Convention for more information.
Rule 1: Should declare public, protected and private in this order and only one time.
Description

Apply to class interface.

Justification

This order emphasizes that which one on a class interface is more important to users of the
class.
The public, protected, and private appear no more than once in a class declaration to make it
easier to distinguish each access section.

Example

The following comply:


class Dog
{
public:
SetColor(const Color &r_color);
SetTail(const Tail &r_tail);
private:
Color m_color;
Tail m_tail;

TMA Confidential

TMA Solutions, 2004

Page 54 of 79

TMA Training Center


Issue Date: Apr 12, 06

C/C++ Coding Guideline

Code: SW-GU-003
Version: 1.0

};

The following do not comply:


class Dog
{
private: // must be at the bottom
Color m_color;
public: //must be on the top
SetColor(const Color &r_color);
private: //just declare one time
Tail m_tail;
public://do not repeat this keyword in declaration
SetTail(const Tail &r_tail);
};

Rule 2: Always order items in an access section.


Description

Apply to class access sections such as public, protected and private.

Justification

The order is constructors, destructor, operators, methods and variables.


This pushes the internal details of a class as low as possible. The most important aspect of
any class is how it is created and destroyed. Therefore, the constructors and destructor are
the first functions. After that, operators are placed ahead of
the other functions to make it as clear as possible which operators are overloaded.

Example

The following comply:


class Fraction
{
public:
//Constructors
Fraction();
//Destructor
~Fraction();
//Operators
Fraction operator
Fraction operator
Fraction operator
Fraction operator
Fraction operator
Fraction operator
Fraction operator
Fraction operator
Fraction operator
Fraction operator
Fraction operator
Fraction operator
Fraction operator
Fraction operator

TMA Confidential

++ ();
-- ();
+ (Fraction fraction);
- (Fraction fraction);
< (Fraction fraction);
<= (Fraction fraction);
> (Fraction fraction);
>= (Fraction fraction);
== (Fraction fraction);
!= (Fraction fraction);
+= (Fraction fraction);
-= (Fraction fraction);
*= (Fraction fraction);
/= (Fraction fraction);

TMA Solutions, 2004

Page 55 of 79

TMA Training Center


Issue Date: Apr 12, 06

C/C++ Coding Guideline

Code: SW-GU-003
Version: 1.0

//member methods
void GetNumerator(int numerator);
int GetNumerator();
void GetDenominator(int denominator);
int GetDenominator();
//check valid denominator (!= 0)
bool IsValidDenominator();
private:
int mi_numerator;
int mi_denominator;
}

The following do not comply:


class Fraction
{
private: // should be at the bottom
int mi_numerator;
int mi_denominator;
public:
//Destructor
~Fraction(); //should be after constructor
//Constructor
Fraction();
//Operator
//member methods
//check valid denominator (!= 0)
bool IsValidDenominator();
}

Rule 3: Do not place anything in protected section except base class.


Description

Apply to class.

Justification

The protected section of a class is the information that is inherited by derived classes. If a
class is final class, it does not make sense to have a protected section.

Example

The following comply:


class BaseClass
{
public:
protected:
int GetKey();
private:
}

TMA Confidential

TMA Solutions, 2004

Page 56 of 79

TMA Training Center


Issue Date: Apr 12, 06

C/C++ Coding Guideline

Code: SW-GU-003
Version: 1.0

//This class will have no derived class


class DerivedClass : public BaseClass
{
public:
private:
}

The following do not comply:


class BaseClass
{
public:
protected:
int GetKey();
private:
}
//This class will have no derived class
class DerivedClass : public BaseClass
{
public:
protected: // should be removed here if not base class
void ActionPerformed();
private:
}

Rule 4: Do not place member variables in public access section.


Description

Apply to class.

Justification

Public member variables declaration violates encapsulation principles. Add a pair of methods
to meet encapsulation principle.

Example

The following comply:


class Product
{
public:
void SetPrice(const double price);
double GetPrice() const;
private:
double md_price;
}

The following do not comply:


class Product
{
public:
double md_price;
}

TMA Confidential

TMA Solutions, 2004

Page 57 of 79

TMA Training Center


Issue Date: Apr 12, 06

C/C++ Coding Guideline

Code: SW-GU-003
Version: 1.0

Rule 5: Always initialize all class member variables in initialization list.


Description

Apply to member variable.

Justification

Some members (non-static constant members, reference members, and members with no
default constructor) must be initialized in an initialization list. For other members,
initializing in an initialization list is preferable for the following reasons:
It is consistent with the members that must be initialized in an initialization list.
It becomes obvious that initialization is being done.
It is more efficient to do so.

Example

The following comply:


//File TreeTrunk.h
class TreeTrunk
{
public:
TreeTrunk();
TreeTrunk(const int circumferenceInInches);
};
//File Tree.h
class Tree
{
public:
Tree();
private:
static const int sm_initialCircumferenceInInches = 10;
TreeTrunk m_treeTrunk;
};
//File Tree.cpp
Tree::Tree(): m_treeTrunk(sm_initialCircumferenceInInches)
{
}

Rule 6: Always ensure the order of variables in declaration and in init list are the same
Description

Apply to variable.

Justification

If the order of variables in initialization list is the same as the order of variables in
declaration, it is very easy for us to maintain source later. Otherwise the initialization list
obscures the constructors behavior.

Example

//File Rectangle.h
class Rectangle
{
public:
Rectangle();
private:
static const int sm_initialHeightAndWidthInInches = 10;

TMA Confidential

TMA Solutions, 2004

Page 58 of 79

TMA Training Center


Issue Date: Apr 12, 06

C/C++ Coding Guideline

Code: SW-GU-003
Version: 1.0

int m_widthInInches;
int m_heightInInches;
};
The following comply:
//File Rectangle.cpp
Rectangle::Rectangle():
m_widthInInches(sm_initialHeightAndWidthInInches),
m_heightInInches(sm_initialHeightAndWidthInInches)
{
}
The following do not comply:
//File Rectangle.cpp
Rectangle::Rectangle():
m_heightInInches(sm_initialHeightAndWidthInInches),
m_widthInInches(sm_initialHeightAndWidthInInches)
{
}

Rule 7: Always make base class destructor virtual


Description

Apply to base class.

Justification

A class with virtual functions and a non-virtual destructor can easily create memory leaks
when a base object pointer is initialized with an instance of a derived class. For instance,
when a derived class is destroyed, the destructor for the derived class
does not get called unless the destructor of the base class is virtual.

Example

The following comply:


class BaseClass
{
public:
BaseClass();
virtual ~BaseClass();
};
class DerivedClass: public BaseClass
{
public:
DerivedClass();
~DerivedClass();
};

The following do not comply:


class BaseClass
{
public:
BaseClass();
~BaseClass();
private:
Color *mp_color;

TMA Confidential

TMA Solutions, 2004

Page 59 of 79

TMA Training Center


Issue Date: Apr 12, 06

C/C++ Coding Guideline

Code: SW-GU-003
Version: 1.0

};
class DerivedClass: public BaseClass
{
public:
DerivedClass();
~DerivedClass();
private:
Shape *mp_shape;
};
BaseClass::BaseClass()
{
mp_color = new Color(red);
};
BaseClass::~BaseClass()
{
delete mp_color;
};
DerivedClass::DerivedClass()
{
mp_shape = new Shape( circle );
};
DerivedClass::~DerivedClass()
{
delete mp_shape;
};
void ArbitraryClass::PerformAction()
{
BaseClass *p_derivedClass = new DerivedClass;
delete p_derivedClass;
}

In this example, the BaseClass and DerivedClass constructors are called when the derived
object is created. However, only the Base destructor is called when the derived object is
deleted.The memory pointed to by mp_shape is never freed. So this causes memory
leak.
Rule 8: Mark virtual for method in derived class when method is virtual in base class
Description

Apply to derived class.

Justification

The virtual keyword is needed only in the base class's declaration of the function; any
subsequent declarations in derived classes are virtual by default. But you have to mark
virtual for method in derived class to make method obvious.

Example

The following comply:


class BaseClass
{
public:

TMA Confidential

TMA Solutions, 2004

Page 60 of 79

TMA Training Center


Issue Date: Apr 12, 06

C/C++ Coding Guideline

Code: SW-GU-003
Version: 1.0

virtual void PerformAction();


};
class DerivedClass: public BaseClass
{
public:
virtual void PerformAction();
};

The following do not comply:


class BaseClass
{
public:
virtual void PerformAction();
};
class DerivedClass: public BaseClass
{
public:
void PerformAction();
};

Rule 9: Do not let compiler generate default constructor.


Description

Apply to constructors.

Justification

If you do not supply any constructors, the compiler attempts to generate a default
constructor. Constructors written by humans are better than constructors generated by
compiler, because they are visible and make construction explicitly.

Example

The following comply:


class A
{
public:
A();
A(int x);
}

The following do not comply:


class A
{
public:
//must declare constructor method here
}

Rule 10: Should declare a copy constructor and assignment operator.


Description

Always apply to classes with pointer data members. Otherwise, if classes without pointer
data members and we do not want to support member-wise of copying and initializing a
object, we declare copy constructor and assignment operator as private attribute when
appreciated.

Justification

Classes with pointer data members that allocate and deallocate memory with constructors
and destructors require copy constructor and assignment operator - overloading.

TMA Confidential

TMA Solutions, 2004

Page 61 of 79

TMA Training Center


Issue Date: Apr 12, 06

C/C++ Coding Guideline

Code: SW-GU-003
Version: 1.0

Note: The compiler uses a copy constructor for objects when you
Initialize one object to another object of the same name.
Pass object by value to method.
Return object by value from method.
If the copy constructor and assignment operator are made private, the compiler ensures that
member-wise copying does not occur in case we do not support member-wise of copying
and initializing a object.
Example

class Tree
{
public:
Tree();
Tree(int hh, int ww);
~Tree();
int GetX();
int GetY();
private:
int m_h;
int m_w;
}

The following do not comply:


class Forest
{
public:
Forest();
~Forest();
void doSongthing();
private:
Tree *mp_tree;
};
Forest::Forest()
{
mp_tree = new Tree;
};
Forest::~Forest()
{
delete mp_tree;
};
void ArbitraryClass::PerformAnotherAction(Forest forest1)
{
Forest forest2 = forest1; //copy constructor
forest2.doAnotherThing();
}
void ArbitraryClass::PerformAction()
{
Forest forest1;
PerformAnotherAction(forest1);

TMA Confidential

TMA Solutions, 2004

Page 62 of 79

TMA Training Center


Issue Date: Apr 12, 06

C/C++ Coding Guideline

Code: SW-GU-003
Version: 1.0

forest1.doSomething();
}

During PerformAnotherAction()s execution, forest1 is copied into forest2. This means that
each instances mp_tree points to exactly the same memory location. When
PerformAnotherAction() finishes execution, forest2 go out of scope, which causes their
destructors to get called forest2 is deleted. Back to function PerformAction(), forest1 was
also deleted, because forest1 and forest2 point to the same memory location. So calling
forest1.doSomething() causes invalid memory access error happens.
To correct this problem - initializations, we must implement the copy constructor.
If we replace above method by the follow, this error occurs again:
void ArbitraryClass:: PerformAnotherAction(Forest forest1)
{
Forest forest2;
Forest2 = forest1 //assignment operator
}

To correct this problem - assignments, we must implement the assignment operator.


The following comply:
class Forest
{
public:
Forest();
Forest(const Forest &r_otherForest);
Forest &operator = (const Forest & r_rightHandSide);
~Forest();
void doSongthing();
private:
Tree *mp_tree;
void CopyData(const Forest &r_forest);
};
Forest::Forest(const Forest &r_otherForest)
{
CopyData(r_otherForest);
}
Forest &Forest::operator = (const Forest &r_rightHandSide)
{
if (this != &r_rightHandSide)
{
CopyData(r_rightHandSide);
}
return *this;
}
void Forest::CopyData(const Forest &r_f)
{
mp_tree = new Tree(r_f.mp_tree->GetX(), r_f.mp_tree->GetY());
}

TMA Confidential

TMA Solutions, 2004

Page 63 of 79

TMA Training Center


Issue Date: Apr 12, 06

C/C++ Coding Guideline

Code: SW-GU-003
Version: 1.0

14. HEADER AND IMPLEMENT FILES CONVENTION


In this section, you will learn to build up class. Things followed to avoid unexpected error happen to us.
Furthermore you can know how to name classes, header files, and implementation files in the same manner.
Please refer to rules in section Class Convention for more information.
Rule 1: Do not include unnecessary header file.
Description

Apply to header and implementation files.

Justification

This rule is to improve compile time and provide better isolation.

Example

The following do not comply:


//File A.h
#include B.h
//File C.h
#include A.h
#include B.h //NOT necessary, AVOID

The following also do not comply:


//File A.h
#include B.h
//File A.cpp
#include A.h
#include B.h

//NOT necessary, AVOID

Rule 2: Should not use path in #include statement.


Description

Apply to header and implementation files.

Justification

This rule is to improve flexibility. That means you can not move included files if using path
in #include statement. Instead, specify the compilers include path.

Example

The following do not comply:


#include <../A.h>
#include ../../CommonService/B.h
#include System/C.h

Rule 3: Should not put methods implementation in header file even inline method.
Description

Apply to all kinds of method.

Justification

This rule exists to separate methods definition from methods implement which allow
developers, who use the method, to focus on methods interface without worrying about
methods implementation.

TMA Confidential

TMA Solutions, 2004

Page 64 of 79

TMA Training Center


Issue Date: Apr 12, 06
Example

C/C++ Coding Guideline

Code: SW-GU-003
Version: 1.0

The following comply:


//File Vehicle.h
class Vehicle
{
public:
double GetPrice();
void SetPrice(double price);
private:
double md_price;
};
//File Vehicle.cpp
double Vehicle::GetPrice()
{
return mb_price;
}
void Vehicle::SetPrice(double price)
{
md_price = price;
}

The following do not comply:


// File Vehicle.h
class Vehicle
{
public:
inline double GetPrice()
{
return mb_price;
}
void SetPrice(double price)
{
md_price = price;
{
private:
double md_price;
};

Rule 4: Should separate inline methods definition from implementation.


Description

Apply to inline method only.

Justification

This rule exists to separate inline methods definition from inline methods implement which
allow developers, who use the method, to focus on methods interface without worrying
about methods implementation

Example

The following comply:


//File Vehicle.h
class Vehicle
{
public:

TMA Confidential

TMA Solutions, 2004

Page 65 of 79

TMA Training Center


Issue Date: Apr 12, 06

C/C++ Coding Guideline

Code: SW-GU-003
Version: 1.0

inline double GetPrice();


inline void SetPrice(double price);
private:
double md_price;
};
// This #include must be after class definition
#include VehicleIL.h
//File VehicleIL.h
inline double Vehicle::GetPrice()
{
return md_price;
};
inline void Vehicle::SetPrice(double price)
{
md_price = price;
};

The following do not comply:


//File Vehicle.h
class Vehicle
{
public:
inline double GetPrice()
{
return md_price;
};
inline void SetPrice(double price)
{
md_price = price;
};
private:
double md_price;
};

The following also do not comply:


//File Vehicle.h
class Vehicle
{
public:
inline double GetPrice();
inline void SetPrice(double price);
private:
double md_price;
};
// The following are inline methods implementation
inline double Vehicle ::GetPrice()
{
return md_price;
};

TMA Confidential

TMA Solutions, 2004

Page 66 of 79

TMA Training Center


Issue Date: Apr 12, 06

C/C++ Coding Guideline

Code: SW-GU-003
Version: 1.0

inline void Vehicle ::SetPrice(double price)


{
md_price = price;
};

Rule 5: Always use forward declaration instead of #include if possible.


Description

Apply to header and implementation files.

Justification

This rule is to improve compile time when coding and to increase dependencies of every
class.

Example

The following do not comply:


// File Forest.h
#include <Tree.h>
class Forest
{
public:
void PlantTree(Tree * p_tree);
};

Whenever Tree.h changes, Forest.h gets unnecessarily recompiled. Instead of including


Tree.h, one can use a forward declaration.
The following comply:
// File Forest.h
class Tree;
class Forest
{
public:
void PlantTree(Tree * p_tree);
};
// File Forest.cpp
#include <Tree.h>
#include <Forest.h>
void Forest::PlantTree(Tree * p_tree)
{
if (0 != p_tree)
{
if (p_tree->IsPlantable())
{
//Do something here
}
}
}

Forward declarations can be used when the compiler needs to know about the mere
existence of a class, rather than the class size. In the above example, the compiler does not
need to know the size of class Tree when compiling Forest.h because p_tree is a pointer to a
Tree. Pointers are a fixed size regardless of what they point to. The compiler only needs to
know that class Tree exists.

TMA Confidential

TMA Solutions, 2004

Page 67 of 79

TMA Training Center


Issue Date: Apr 12, 06

C/C++ Coding Guideline

Code: SW-GU-003
Version: 1.0

Note: One more thing you must know that forward declaration cant be replaced by #include
in case of circle-calling. Look into the following example:
//File A.h
#include B.h
class A
{
public:
void Method1();
void Method2();
};
//File A.cpp
int A::Method1()
{
//Do something here
}
//In this method, we refer to class B
int A::Method2()
{
//Call Method3 of class B
//Do something here
}

In header file B.h, if we use #include A.h instead of class A, compile error will occur. So
forward declaration is a must in this case.
//File B.h
class A; //This is forward declaration
class B
{
public:
void Method3();
void Method4();
//.
};
//File B.cpp
#include A.h
#include B.h
int B::Method3()
{
//Do something here
}
//In this method, we refer to class A
int B::Method4()
{
//Call Method1() of class A
//Do something here
}

TMA Confidential

TMA Solutions, 2004

Page 68 of 79

TMA Training Center


Issue Date: Apr 12, 06

C/C++ Coding Guideline

Code: SW-GU-003
Version: 1.0

Rule 6: Dont define non-static variable in header file except constant variable.
Description

Do not apply to class member.

Justification

If a non-static variable definition exists in a header file and the header file is included in
two .cpp files, the variable is defined twice, which is an error.

Example

The following comply:


namespace HIGHWAY
{
const unsigned int MAX_NUM_VEHICLES = 100;
};

The following do not comply:


namespace HIGHWAY
{
unsigned int n_maxNumberVehicles;
};

If the maximum number of vehicles is not constant, the following comply:


// File highway.h
namespace HIGHWAY
{
extern unsigned int n_maxNumVehicles;
};
// File highway.cpp
unsigned int HIGHWAY::n_maxNumVehicles = 100;

Rule 7: Do not define an aggregate variable or member in a header file even constant.
Description

Apply to global variable only.

Justification

If aggregate variable is defined in header file, compile error will occur when the header file
is included in more than one implementation file.
In C++, an aggregate is one of the following:
an array
a class or structure with none of the following:
user-defined constructors
private non-static data members
protected non-static data members
non-static reference members
non-static constant members
base classes
virtual functions

Example

The following comply:


// File highway.h
namespace Highway
{

TMA Confidential

TMA Solutions, 2004

Page 69 of 79

TMA Training Center


Issue Date: Apr 12, 06

C/C++ Coding Guideline

Code: SW-GU-003
Version: 1.0

extern const unsigned int na_maxNumVehicles[];


};
// File highway.cpp
const unsigned int Highway::na_maxNumVehicles[] = {100, 200};

The following do not comply:


// File highway.h
namespace Highway
{
const unsigned int na_maxNumVehicles[] = {100, 200};
};

Rule 8: Always separate each class from specific header and implementation files.
Description

Apply to class only.

Justification

This makes easier to read your source code files. This also improves the version control of
the files; for example the file containing a stable class declaration can be committed and not
changed anymore.

Example

The following comply:


// File A.h
//Declaration of class A
class A
{
public:
A();
virtual ~A();
};
// File A.cpp
//Implementation of class A
A::A()
{
}
A::~A()
{
}
// File B.h
//Declaration of class B
class B
{
public:
B();
virtual ~B();
};
// File B.cpp
//Implementation of class B
B::B()
{
}

TMA Confidential

TMA Solutions, 2004

Page 70 of 79

TMA Training Center


Issue Date: Apr 12, 06

C/C++ Coding Guideline

Code: SW-GU-003
Version: 1.0

B::~B()
{
}

The following do not comply:


// File A.h
//Declaration of class A
class A
{
public:
A();
virtual ~A();
};
//Declaration of class B
class B
{
public:
B();
virtual ~B();
};
//File A.cpp
//Implementation of class A
A::A()
{
}
A::~A()
{
}
//Implementation of class B
B::B()
{
}
B::~B()
{
}

Note: Refer to rule #14 of Naming Convention section for more information.

15. CLASS DESIGN CONVENTION


Experiences show that the good programs are designed, coded, tested well and lots of other factors relating to
success of software.
With a piece of experience, I just want to give out some needs which programs must follows to improve
software as good as possible.
Rule 1: Should consider the following class design checklist as critical need.
Description

When designing classes, several questions are given out as follows:

TMA Confidential

TMA Solutions, 2004

Page 71 of 79

TMA Training Center


Issue Date: Apr 12, 06

C/C++ Coding Guideline

Code: SW-GU-003
Version: 1.0

What behaviors do I need?


Do I need to overload operators?
Are the compiler defaults correct?
What user-defined conventions do I need?
Good class design requires an understanding of how applications use objects. This
knowledge helps you design object behaviors and determine what parts of your objects you
should encapsulate.
Justification

Example

Follow this checklist as we design classes, because an extensive set of guidelines is helpful.
They do not exactly fit the requirements of all objects, but we should think about, even if
they do not apply to all objects when designing classes.
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.

Initialization
Copy constructor
Default constructor
Assignment operator
Destructor
Conversions
Relational operators
Arithmetic operators
Input and output
Subscription operator[] and iteration operators()
Non-member or member methods implementation

Please refer to book Navigating C++ and Object-Oriented Design, page 331 for more
information.

Rule 2: Should use destructor to prevent resource leaks.


Description

Apply to designing class.

Justification

If we use pointer in program, opportunities for resource leaks increase in number. Because
we are beforehand with this problem, so we had better overcome it. This rule is to help
preventing resource leaks by using destructor.
Please refer to book More Effective C++ - 35 New Way Improve Your Programs and
Designs, page 45 for more information.

TMA Confidential

TMA Solutions, 2004

Page 72 of 79

TMA Training Center


Issue Date: Apr 12, 06
Example

Code: SW-GU-003
Version: 1.0

C/C++ Coding Guideline

Scenario:
There are three classes in hierarchy tree as following:
LittleAnimal

Puppy

Kitty

LittleAnimal is an abstract base class. Puppy and Kitty are concrete derived classes. A virtual
method, ProcessAction(), handles the necessary specific processing. Look below samplecode:
class LittleAnimal
{
public:
virtual void ProcessAction() = 0;
//.
};
class Puppy : public LittleAnimal
{
public:
virtual void ProcessAction();
//.
};
class Kitty : public LittleAnimal
{
public:
virtual void ProcessAction();
//.
}
void ProcessMultipleAction(istream &dataSource)
{
while (dataSource)
{
LittleAnimal *p_littleAnimal = readNextAnimal(dataSource);
p_littleAnimal->ProcessAction();
delete p_littleAnimal;
}
}

What happens if p_littleAnimal->processAction() throw an exception.


ProcessMultipleAction fails to catch exceptions, so the exception propagates to
ProcessMultipleActions caller and p_littleAnimal is never deleted.
Solution 1: Using try-catch to overcome the resource leak.
void ProcessMultipleAction(istream &dataSource)
{
while (dataSource)
{
LittleAnimal *p_littleAnimal = readNextAnimal(dataSource);
try
{
p_littleAnimal->ProcessAction();

TMA Confidential

TMA Solutions, 2004

Page 73 of 79

TMA Training Center


Issue Date: Apr 12, 06

C/C++ Coding Guideline

Code: SW-GU-003
Version: 1.0

Rule 3: Should avoid resource leaks in constructors.


Description

Apply to designing class.

Justification

If you use pointer in your program, opportunities for resource leaks increase in number. If
we are beforehand with, then it had better overcome it. This rule is to help preventing
resource leaks in constructors.

Example

Please refer to book More Effective C++ - 35 New Ways Improve Your Programs and
Designs, page 10 for more information.
Scenario:
In software development, you might come up with design like this:
class Image
{
public:
Image(const string& imageDataFileName);
//.
};
class AudioClip
{
public:
AudioClip(const string& audioDataFileName);
//.
};
class PhoneNumber
{
//holding phone number
};
class BookEntry
{
public:
BookEntry(const string &name, const string address = ,
const string &imageFileName,
const string &audioClipFileName);
~BookEntry();
//.
Private:
string m_theName;
string m_theAddress;
Image *mp_theImage;
AudioClip *mp_theAudioClip;
//.
};
BookEntry::BookEntry(const string &r_name,
const string &r_address = ,
const string &r_imageFileName,
const string &r_audioClipFileName)
:
m_theName(r_name),
m_theAddress(r_address),
mp_theImage(0),
mp_theAudioClip(0)
{

TMA Confidential

TMA Solutions, 2004

Page 74 of 79

TMA Training Center


Issue Date: Apr 12, 06

C/C++ Coding Guideline

Code: SW-GU-003
Version: 1.0

if ( != r_imageFileName)
{
mp_theImage = new Image(r_imageFileName);
}
if ( != r_audioClipFileName)
{
mp_theAudioClip = new AudioClip(r_audioClipFileName);
}
}
BookEntry::~BookEntry()
{
delete mp_theIamge;
delete mp_theAudioClip;
}

What happens if operator new is unable to allocate enough memory for an AudioClip Object
- new AudioClip(r_audioClipFileName). Who deletes the object which mp_theImage already
points to? NO BODY because the destructor wont be called if the object isnt fully
constructed.
Solution 1: Using try-catch to overcome the resource leak in constructor.
BookEntry::BookEntry(const string &r_name,
const string &r_address = ,
const string &r_imageFileName,
const string &r_audioClipFileName)
:
m_theName(r_name),
m_theAddress(r_address),
mp_theImage(0),
mp_theAudioClip(0)
{
try
{
if ( != r_imageFileName)
{
mp_theImage = new Image(r_imageFileName);
}
if ( != r_audioClipFileName)
{
mp_theAudioClip = new AudioClip(r_audioClipFileName);
}
}
catch()
{
delete mp_theImage;
delete mp_theAudioClip;
}
}

This is OK, but dont make sense if mp_theImage and mp_heAudioClip are constant
pointers.
If you try to put these constant pointers in initialization list, then you cant implement trycatch to protect resource leak when exception is thrown. Nevertheless, you can make two
private static member methods that return initialized pointers.
This is perfect but
+ youve been laboring to overcome the problem.
+ you have a bad headache when maintenance because constructor is dispersed across

TMA Confidential

TMA Solutions, 2004

Page 75 of 79

TMA Training Center


Issue Date: Apr 12, 06

C/C++ Coding Guideline

Code: SW-GU-003
Version: 1.0

several methods.
Solution 2: Using auto_ptr instead of raw pointers.
class BookEntry
{
public:
BookEntry(const string &r_name,
const string &r_address = ,
const string &r_imageFileName,
const string &r_audioClipFileName);
~BookEntry();
//.
Private:
string m_theName;
string m_theAddress;
const auto_ptr<Image> mp_theImage;
const auto_ptr<AudioClip> mp_theAudioClip;
};
BookEntry::BookEntry(const string &r_name,
const string &r_address = ,
const string &imageFileName,
const string &audioClipFileName)
:
m_theName(r_name),
m_theAddress(r_address),
mp_theImage( != r_imageFileName ?
new Image(r_imageFileName), 0),
mp_theAudioClip( != r_audioFileName ?
new AudioClip(r_audioClipFileName):0)
{
}
BookEntry::~BookEntry()
{
}

How is your feeling about this solution?


Its very robust in class design and the face of exceptions, isnt it?

TMA Confidential

TMA Solutions, 2004

Page 76 of 79

TMA Training Center


Issue Date: Apr 12, 06

Code: SW-GU-003
Version: 1.0

C/C++ Coding Guideline

APPENDIX: C++ KEYWORDS


C++ has the following keywords:
and
and_eq
asm
auto
bitand
bitor
bool
break
case
catch
char
class
compl
const
const_cast
continue
default
delete
do

double
dynamic_cast
else
enum
explicit
export
extern
false
float
for
friend
goto
if
inline
int
long
mutable
namespace
new

not
not_eq
operator
or
or_eq
private
protected
public
register
reinterpret_cast
return
short
signed
sizeof
static
static_cast
struct
switch
template

this
throw
true
try
typedef
typeid
typename
union
unsigned
using
virtual
void
votatile
wchar_t
while
xor
xor_eq

Basic naming recommendations


Names should normally be formed from two or more parts: an action (verb) and an object (noun) of the action.
A combination of plane English words should be used for the names.
Each word forming the name is capitalized.
When three or more words are used, follow the below basic arrangement:
Verb Noun:
GetNum, SetName
Verb Adjective Noun:
GetActiveName0
Verb Noun Preposition Noun:
CreateGeomFromWkb, CloseSession, SetTime
N
o.
1
2

Words & phrases

Meaning

Set
Get

Set
Get

Verb
Verb

Create

Create

Verb

Destroy

Destroy

Verb

TMA Confidential

N
o.
11
1
2
1
3
1

Words &
phrases
Info
Active

Meaning
Noun
Adjective

First

Information
As the present
object
First

Next

Next

Adjective

TMA Solutions, 2004

Adjective

Page 77 of 79

TMA Training Center


Issue Date: Apr 12, 06

Code: SW-GU-003
Version: 1.0

C/C++ Coding Guideline

Name

Name

Noun

Count, Cnt

Count

Noun

Max

Max

Noun

Min

Min

Noun

QueryDef

Query

Noun

1
0

Table, Tbl

Table

Noun

4
1
5
1
6
1
7
1
8
1
9
2
0

New

New

Adjective

All

All

Adjective

By

By

Preposition

To

To

Preposition

From

From

Preposition

Hungarian naming method


TYPE
All
CONST

Meaning
Global var
Constant
member variable
static member variable
ANSCIIZ string( NULL-end string)

Sample
GsErrorCode
cValue

SZ

Pre-fix
G
c
m_
S
sz

PSHORT
PUSHORT
PLONG
PULONG
PCH
PUC
PSZ

ps
pus
pl
pul
pch
puc
psz

psErrorCode
pusLineNo
plSeekPointer
pulFunctionNo
pchName
pucColor
pszString

CHAR
UCHAR

c
ch
uc

SHORT
USHORT

s
us

LONG

ULONG

ul

FLOAT
DOUBLE
N/A

n64
u64
f
dbl
N/A

Pointer for short var


Pointer for unsigned short var
Pointer for long var
Pointer for unsigned long var
Pointer for char var
Pointer for unsigned char var
Pointer for ASCIIZ string (NULL-end
string)
Class defined by user
char var
Unsigned char var
BYTE(unsigned char)
Short var
Unsigned short var
WORD(unsigned short)
Long var
LONG(long)
Unsigned long var
DWORD(unsigned long)
64-bit integer
64-bit unsigned integer
Float var
double
Structure name does not have prefix.

TMA Confidential

TMA Solutions, 2004

SsubLineNo
szString

chMotor
ucColor
sErrorCode
usLineNo
lSeekPointer
ulFunctionNo

fVariable
LogDate

Page 78 of 79

TMA Training Center


Issue Date: Apr 12, 06

C/C++ Coding Guideline


(Except global, static pointer case)
Structure member has prefix as normal var.

Code: SW-GU-003
Version: 1.0
LogDate.usDay

---------- End of Document ----------

TMA Confidential

TMA Solutions, 2004

Page 79 of 79

Das könnte Ihnen auch gefallen