You are on page 1of 23

Coding

Convention

Version

Author

Date

1.1

Frdric Alaphilippe

30/03/06

INTRODUCTION:.............................................................................................................................................4
I. Coding Style Conventions..............................................................................................................................5
I.1. Modules naming....................................................................................................................................5
I.2. Files........................................................................................................................................................5
I.3. Use name space....................................................................................................................................5
I.4. Class......................................................................................................................................................6
I.5. Methods.................................................................................................................................................6
I.5.a. Classical methods ........................................................................................................................7
I.5.b. Accessors .....................................................................................................................................7
I.5.c. Accessors-like methods ................................................................................................................7
I.5.d. WIN32 functions ...........................................................................................................................8
I.6. Data.......................................................................................................................................................8
I.6.a. Static data: g_myStaticData...........................................................................................................9
I.6.b. Member data: m_myMemberData..................................................................................................9
I.6.c. Global member data: mg_myGlobalMemberData .........................................................................9
I.6.d. Local variable.................................................................................................................................9
I.6.e. Pointer: pMyPointer........................................................................................................................9
I.6.f. Smart pointer: spMySmartPointer.................................................................................................10
I.6.g. HANDLE: hMyHandle...................................................................................................................10
I.6.h. WIN32...........................................................................................................................................10
I.6.i. Enums............................................................................................................................................10
DATA NAMING SUMMARY TABLE.....................................................................................................11
II. Code management.....................................................................................................................................12
II.1. Layout..................................................................................................................................................12
II.1.a. Readable code............................................................................................................................12
II.1.b. Blocks between { }.......................................................................................................................12
II.2. Header Comments.............................................................................................................................12
II.3. Cpp Comments..................................................................................................................................12
II.3.a. Algorithmic steps comments........................................................................................................12
II.3.b. Bug management........................................................................................................................13
II.3.c. Visual Studio Task List process...................................................................................................13
II.4. New module coded using wide string..................................................................................................13
II.5. STL classes.........................................................................................................................................14
II.6. Kobra Messages Mgt base..................................................................................................................14
II.7. Target platform when you use WIN32................................................................................................14
II.8. Virtual and static methods...................................................................................................................14
II.9. typedef ...............................................................................................................................................15
II.10. pragma once and #ifndef...................................................................................................................15
II.11. Initialization of all variables................................................................................................................15
II.12. Deleted pointers setted at 0.............................................................................................................15
II.13. Assert used efficiently.......................................................................................................................15
II.14. Memory allocation tested..................................................................................................................16
II.15. MSXML..............................................................................................................................................16
III. COM...........................................................................................................................................................17
III.1. Methods for external using.................................................................................................................17
III.2. Methods for internal using..................................................................................................................17
III.3. Returned value management.............................................................................................................18
IV. Exporting template class and STL.............................................................................................................19
IV.1. Problematic........................................................................................................................................19
IV.2. Solution and limitation........................................................................................................................19
IV.2.a. Explicit Template Instantiation...................................................................................................19
IV.2.b. Limitation....................................................................................................................................19
IV.3. What to do..........................................................................................................................................20
IV.4. Ref .....................................................................................................................................................20
V. APPENDIX..................................................................................................................................................21
V.1. APPENDIX A: doc++..........................................................................................................................21
V.2. APPENDIX B: smart pointer...............................................................................................................23

INTRODUCTION:
Goals: Improve code clarity and consistency.
See what helps avoiding bugs.
Use a natural language, an easier writing.
Flag what is atypical by a different marker.
Keep coherency between conventions.

Advised => you are cheered on doing it


Restriction => you must not do this
Mandatory => you must do this
Definitions:
Pascal case: The first letter in the identifier and the first letter of each
subsequent concatenated word are capitalized.
Ex:
Camel case: The first letter of an identifier is lowercase and the first letter of
each subsequent concatenated word is capitalized.
Ex:

I. Coding Style Conventions


Mandatory:
When you modify an old module:
- new classes, new methods, new member data must follow whole
convention
- change existing code according to convention if you have time (and if it is
safe)
Of course if you create a new module, use whole convention.

I.1. Modules naming


Pascal case is allowed or only lower case letters.
Ex:

Restriction: no space, no accent, no underscore.


Mandatory: Only USASCII.

I.2. Files
Advised: Only one <class>.cpp / <class>.h by class.
Restriction: No implementation in class definition in .h.
Mandatory: Write inlines below class definition, and maximum code in .cpp.

I.3. Use name space


Mandatory: Use name space for all new modules
(not only in Third Party modules.)
Only lower case letters.
Some tests have been made about crash in method using name space.
DrWatson and Dump are still usable. We retrieve all needed information (ie
corresponding namespace).

Advised:
Try to choose short namespaces.
Ex:
Thanks namespace we also avoid potential conflict with simple system
structures.

Ex:

Restriction: never write using namespace at beginning of your .cpp.

I.4. Class
Mandatory: Pascal case, underscore is allowed. Only USASCII.
No need common prefix for all classes of same dll, because we use namespace.
Use following minimal Canonical class.
Ex:

Remark1: Both are implemented in .cpp even if they stay empty. It facilitates
patching and debugging.
Remark2: Destructor always virtual.
(except if class has none virtual method and is not derivated: to avoid a virtual
table being created).
Remark3:Both are in private and not implemented to avoid somebody using it. If
someone try using it, it will fail when compiling.

Mandatory:
Use initialization list in constructor.
Ex:

I.5. Methods
Mandatory: Camel case. Only USASCII.
Ex:

Mandatory:
When a method doesnt modify the class, precise it with const at end.
Ex:

Warning: Do not use const when you are in COM context.


Restriction: When you set parameter, don't use !!(sometimes used because of
overlapping of operator !), nor !N=Upointer.
LL

I.5.a. Classical methods


Mandatory:
- Begin by a verb. It symbolizes one action.
Ex:
- Returned error value:
Mandatory: When somebody uses a method which returns Boolean (or error
code, HRESULT), he must test this value.

I.5.b. Accessors
Mandatory:
To access data: begin by /gese
tt
To test bool: begin by is
To test property: begin by has

I.5.c. Accessors-like methods


Mandatory:

I.5.c.1. To get an object without getting ownership


Warning: Never use get in method name if user must delete returned pointer.
We must ALWAYS test this returned pointer to use it.
When we access member data (which is not a pointer), we can also use:
Remark: const is according to using.
We can use a returned error code if needed (bool or HRESULT or specific enum
of error values):
, but in this case we must test the returned code to use the pointer.
Important: If this returned code is true (or if (if SUCCEDED()) is true), we
consider that the pointer is not NULL and we neednt test this pointer later
to use it.

I.5.c.2. To get the ownership of a pointer


I.5.c.2.a Detach

Detach an object still created (or not: in this case pointer is null). User must test
pointer before using it and he must delete it later.
or
This a deal with caller. If a caller uses ppObj instead of classical &pObj, he must
test himself the pointer before calling detachObject.
Using sample:
I.5.c.2.b Clone

Clone an object still created (or not: in this case pointer is null). User must test
pointer before using it and he must delete it later.
Or
If this returned code is true (or if (if SUCCEDED()) is true), we consider that the
pointer is not NULL and we neednt test it to use it.
I.5.c.2.c Create

Creation method:
If this returned code is true (or if (if SUCCEDED()) is true), we consider that the
pointer is not NULL and we neednt test it to use it.
Remark: About creation, only one way it can not return directly the object.

I.5.d. WIN32 functions


Always prefix function with ::

I.6. Data
Mandatory: Camel case. Only US-ASCII.
Use explicit name for variable. State clearly what are your variables.
Add a W when you use wide data in module not compiled with UNICODE flag
Ex:

Restriction:
No abbreviation.
8

Ex:
int uFS; //instead of nUserFontStyle

Mandatory:
To clarify your algorithms, use int indexName instead of int i, j.
Ex:

I.6.a. Static data: g_myStaticData


Mandatory:
Associate the data name with g_ as for member data.
Ex:

Advised: Avoid to use them when you can.


I.6.b. Member data: m_myMemberData
=> corresponding with standard mfc, ATL,
Member data are protected or private, never public (use accessors).

Advised:
Use accessors also in derivated classes.

Mandatory:
When this is a member data, associate the data name with m_ .
Ex:

I.6.c. Global member data: mg_myGlobalMemberData


The class is considered as a namespace, so this is as a global variable of which
we reduce the reach to only one class.

I.6.d. Local variable


Mandatory: Camel Case
Advised:
If in a method, this might be an ambiguity, specify types.
Ex:

I.6.e. Pointer: pMyPointer


Warning: This is obvious, but dont forget to check any pointer
Ex:

I.6.f. Smart pointer: spMySmartPointer

Warning: According to ATL:


- a pointer on IDispatch: pIDispatch
- but a smart pointer on IDispatch: spDispatch (the I disappears)

I.6.g. HANDLE: hMyHandle


Set h ahead an handle
=> to always know you manipulate an handle.
Ex:

I.6.h. WIN32
When you use specific API WIN32, adjust your variable naming to the WIN32
style.
Ex:

I.6.i. Enums
Mandatory:
Begin elements of enum by a prefix (initials of enum name or beginning of this
name to set a scope).
Ex:

10

DATA NAMING SUMMARY TABLE


Local variable
Just be explicit

Member data
m_myMemberData

Static data
g_myStaticData

integer

nVar

m_nVar

g_nVar

float

fVar

m_fVar

g_fVar

bool

isReady
hasData
bResult

m_isReady
m_hasData
m_bResult

g_isReady
g_hasData
g_bResult

m_pMyPointer
m_spMySmartPointer
m_hFile

g_pMyPointer
g_spMySmartPointer
g_hFile

Data

Pointer
pMyPointer
Smart pointer spMySmartPointer
Handle
hFile
Specific API WIN32
Enums

WIN32 style
Begin elements of enum by a prefix

11

II. Code management


II.1. Layout
II.1.a. Readable code
Always get your code more readable !

Mandatory: About blocks:


Always add a space after keywords (like if, for , while), around affectation (=)
and around arithmetical and logical operators (like ==, &&, !=, except *)
Ex:

II.1.b. Blocks between { }


Whichever is the number of lines in a block, add { }.

Restriction:
you cant set breakpoint on such a line.
It allows:
- to write clearer code,
- to add easily code, because {} are still there
- to facilitate merging, because {} and tabulations are still there
Ex:

II.2. Header Comments


Mandatory: In English.
In .h use DOC++ format to comment all your classes, methods and member
data.

II.3. Cpp Comments


II.3.a. Algorithmic steps comments
=> to make clearer methods

Advised: When you have some imbricated tests, you can call to mind at end of
test
Ex:

12

II.3.b. Bug management


Mandatory:
To avoid being forced to always open Notes, add information in .cpp when you fix
a bug.
If somebody has a problem with the code located around a bug fix, he will know
directly who to ask information for.
Ex:

II.3.c. Visual Studio Task List process


To use these comments, you must be in a Visual Studio project.

Mandatory:
To add a comment hyperlink to the Task List window, enter one of following
comments: ,TOH
, UNDON
E
and the comment text.
Ex:
// TODO <yo u r dev account name> <fixed date>: Fix
A hyperlink to your comment will appear in the Task List.

this function.

Remark: When we finish a development, always check the Task List.

Warning: This task list is only available on opened files.


So a text file will be created with TODO list during daily compilation.

II.4. New module coded using wide string


Mandatory:
To avoid conversions and improve performances, use the Unicode win32 API
Efficient conversion is done with

13

bool KO_I18NUtil::mb2wide(const char* from, int len, std::wstring& to)

from lib koi18nutil.


Ex:
Remark: If you dont include Rogue Wave, you can use directly:

II.5. STL classes


Mandatory:
Use std::list, std::map (except about archiving when you must stay back
compatible and continue using Rogue Wave structures for example).

II.6. Kobra Messages Mgt base


Restriction:
Dont write directly your messages in code.
But use identifiers coming from Kobra Messages Mgt Lotus Notes base.

II.7. Target platform when you use WIN32


Always check the target platform in bottom description of an API
Ex:
In MSDN:

II.8. Virtual and static methods


Mandatory:
When you override a virtual method, add keyword virtual before all overridden
methods definitions of derivated classes.
=> To avoid problem if somebody removes the top virtual statement
=> To ease reading, to avoid reader searching all inherited class to check if
method is virtual

Mandatory:
Add //virtual or //static above method implementation in .cpp.
=> For documentation

14

II.9. typedef
Forbidden when only for one type. Might be used to manage very long template
definition (stl map ...).
Advised:
Remind the type defined by typedef in commentary at beginning of method.

II.10. pragma once and #ifndef


In .h, we must add both:
pragma avoids re-opening file, so it allows sparing time during compilation.

II.11. Initialization of all variables


Mandatory:
Always initialize variable with default value.

Restriction:
Remark: If we dont enter in condition block (or if someone sets later the block
between {} in commentary), there will be none initialization.

II.12. Deleted pointers setted at 0


Mandatory:
Each time you delete a pointer, set it immediately at 0.
Because if you call just after a method using this pointer, the test if
(pData != 0) will not avoid potential crash.

II.13. Assert used efficiently


Restriction:
- Never code in assert:
- You must not build any variable to test in an assert statement, or only using
#ifdef DEBUG

Mandatory:
Test outside assertion and dont forget to manage the case of error:

15

II.14. Memory allocation tested


Advised:
Ex:

II.15. MSXML
We use version 3.0

16

III. COM
Always use Smart pointer CComPtr (See See
\\groupsrv01\kobra\etc\scripts\DOC++\Documentations Doc++ uses commentary
preceding declarations of class, of methods, of fonctions, of typedefs, of macro,
according to following: ).
Raw interface pointer should only be used to maintain code that has been written
in old style.
Dont use the _bstr_t, _variant_t, _com_ptr_t that can be generated by the
#import directive (because they generate some C++ exceptions instead of
returning hResults).
Always use the ATL smart types: CComBSTR, CComVariant, CComPtr,
CComQIPtr, CComDispatchDriver

III.1. Methods for external using


Mandatory: For external use
Ex1:

Restriction: Dont use reference for interface => always **

Warning:
if you want to force internal pointer to be released, call:
spName .Release();
spName->Release() can not be compiled.
Ex2:
Only for maintenance

III.2. Methods for internal using


Restriction: Never for external using.
Only for internal using, and of course if you are sure to always have the interface.
But you must test if CComPtr is empty.
C=>
g
ComP
r
t
>Addref is contained in CComPtr.
e
m
a
N
I
<

17

Warning:
Ex1: ERROR
=> Problem: a release has been done. The pointer is on released data !
Ex2:
=> No Problem: Addref is transferred in sp.
Ex3:
Only if we have no choice and must use a basic pointer:

III.3. Returned value management


Mandatory:
Return errors by HRESULT.
Ex:

Restriction:
Never convert hr in Boolean.
Never lose the error code through different called methods.
Always use the SUCCEEDED and FAILED macros (except for MSXML see
below) to test the result of a method call. If a pointer is returned, it is valid when
succeeded is true. .
There is no need to test the pointer again.

Warning:
About MSXML (about loading of a file for example), MSXML returns S_FALSE to
manage errors. .
S_FALSE is a succeeded code for COM, therefore you have to compare the
HRESULT with S_OK :
Note: If you still persist to use the succeeded macro with MSXML, you also have
to test the pointer.

18

IV. Exporting template class and STL


Mandatory:
As a rule, everything that is accessible to the DLL's client (according to C++
access rules) should be part of the exportable interface. This includes private
data members referenced in inline functions.

IV.1. Problematic
If you have a template SomeTemplate<T>, it is not marked with dllexport
because you can only export definitions, not declarations, and a template is not a
definition. Its code is only created when you create an instantiation.
So when you have this:
Then SomeTemplate<int> is an instantiation of SomeTemplate<T> that is
accessible to clients of AClass but is not exported!
Now, if AClass was not exported and you tried to use it in some importing code, it
works just fine!
In calling code, whenever you might use SomeTemplate<int>, the compiler is
going to automatically instantiate SomeTemplate<T>, creating a local version of
SomeTemplate<int>. There are the same code, so all the same symbols are
defined, and there are no link errors.
Now we have two versions of SomeTemplate<int>.

IV.2. Solution and limitation


IV.2.a. Explicit Template Instantiation
You must use the template class pre-instantiation method:

IV.2.b. Limitation
If you have some DLL with an exported class containing a std::vector<int> that
you have explicitly instantiated and exported as shown above, your C4251
warnings are fixed.
But then you want to use another DLL that has an exported class containing a
std::vector<int> with the same explicit-instantiation workaround
When you try to link to both DLLs at the same time, you will get multiply-defined
symbol errors!
Both DLLs contain a specific class called std::vector<int>. They each have a
copy of the symbols generated during template instantiation. The linker has no
idea that the symbols are the same because the underlying code is the same,
because it's in the compiled DLLs that it doesn't have access to. So it spits out
link errors....

19

IV.3. What to do
For all STL include use:
Use something like for the class:
In the Header:
or:
The best way to avoid all this could be to not export template classes.
If you use template only in the private part of your class you dont have the
problem.
Private symbols dont need to be exported.

IV.4. Ref
http://support.microsoft.com/kb/q168958/
http://support.microsoft.com/default.aspx?scid=kb;en-us;172396

20

V. APPENDIX
V.1. APPENDIX A: doc++
See \\groupsrv01\kobra\etc\scripts\DOC++\Documentations
Doc++ uses commentary preceding declarations of class, of methods, of
fonctions, of typedefs, of macro, according to following:
or (on one line):
Doc ++ keywords
@memo
@return
@param @warning
@important @exception
@see @remark
@author
@version
@ifdef @example
@deprecated @kdtdescription

21

Doc++ macro
##
@@
\\
{\tiny }
{\footnotesize }
{\large }
{\LARGE }
{\Huge }
\hline
\begin{center}
\end{center}
\begin{flushright}

\end{flushright}
\begin{itemize}
\item
\item[ - ]
\end{itemize}

Typewriter style
Carriage return
Carriage return
Tiny
Small
Large
Larger
Huger
Line insertion

{\bf }
bold
{\it }
italic
{\tt }
Typewriter style
{\scriptsize }
Very small
{\small }
Nearly small
{\Large }
Plus grand
{\huge }
Huge
{\HUGE }
More huger
{\underline }
Underline
\begin{flushleft}
Center block
Left aligned block
\end{flushleft}
\begin{verbatim}
Right aligned block
Keep block design
\end{verbatim}

Value list

\begin{enumerate}

\item
Enumerated list
\item [ - ]
\end{enumerate}

\begin{description}
Value list with

bullets identical in
\item
each level
\end{description}
\URL{}

Specify a link

\URL[]{adr...}

\Ref{}

Reference to one
\Ref[]{adr}
doc point

22

Specify a link to
adr
Reference to one
point adr of the doc

V.2. APPENDIX B: smart pointer


Smart pointers are objects which store pointers to dynamically allocated (heap)
objects. They behave much like built-in C++ pointers except that they
automatically delete the object pointed to at the appropriate time.
Smart pointers are particularly useful in the face of exceptions as they ensure
proper destruction of dynamically allocated objects.
Conceptually, smart pointers are seen as owning the object pointed to, and thus
responsible for deletion of the object when it is no longer needed.
Use CComBSTR::Attach to attach a CComBSTR to an existing BSTR without
copying it.
CComBSTR has many useful methods such as +=, so sometimes
std::basic_string can be avoided.
When returning BSTRs from methods, use Detach() on CComBSTR:
*pOut = CComBSTR(L"hello there").Detach();

23

You might also like