Copyright � 1998, 2000, 2004 Syntext, Inc.
Permission is granted to any institution or individual to use, copy, modify, and distribute this document, provided that this complete copyright and permission notice is maintained intact in all copies.
Syntext, Inc. makes no representations about the suitability of this document or the examples described herein for any purpose. It is provided “ as is ” without warranty of any kind.
E-mail suggestions to: info-general@syntext.com
Table of Contents
List of Examples
Table of Contents
This document is mostly based on the papers listed in the bibliography. They prescribe conceptual rules some of which may be settled differently (e.g, variable naming conventions). These papers also prescribe detailed explanations for the rule settlements.
This paper prescribes the concrete rules for Syntext project development.
In development it is necessary to follow coding conventions for the following reasons:
It is necessary to avoid the typical coding mistakes
It is necessary to unify the view of different code fragments
In any code fragment any project programmer has to understand semantics rapidly
New people can get up to speed quickly
In some typical situations it is convenient to apply a worked out coding style for performance increase (both human and computer).
Because of the above-mentioned reasons source code ought to satisfy the following:
Should be consistent (has complete structure)
Should be clear for reading and comprehension
Should be portable
Must not contain typical mistakes
Available to any programmer for modification
Must not lead to performance loss.
The following definitions are used in the paper:
Rule - statement that must be strictly obeyed.
Recommendation - statement that should be followed if it does not lead away from prescribed goals and does not contradict the common sense.
Rule.� If a rule is broken it has to be explicitly documented.
Recommendation.� Code is optimized only in the case of special performance requirements. Code is optimized only in extreme cases.
Rule.� Code must never be copy/pasted (literally doubled). If two functionalities have the common parts, they must reuse single code portion.
Rule.�
Header files have
.h
extension.
Rule.�
Implementation files have
.cxx
extensions.
Rule.�
Automatically generated files have
.hpp
and
.cpp
extensions correspondingly.
Recommendation.� Each header-implementation couple should contain not more than one class definition/implementation.
Rule.�
Header and implementation classes have to be named as the contained class+extension (case-sensitive). If class implementation is too large it may be split to files named like:
ClassName_section.cxx
Rule.�
If files contains a collection of entities (classes, functions, variables, macro), then the file is named with lowercase letters divided with underscores, e.g.
gui_geometry_structs.h(.cxx)
.
Rule.� Each header file must prevent second inclusion. (See Example�1.1, “Second inclusion prevention” ). Macro names are to follow the pattern: MY_NAMESPACE_MY_CLASS_H.
Rule.�
#include < >
directives must not include relative paths like
'../'
.
Example�1.1.�Second inclusion prevention
// This file contains the implementation of
// MyClass. Hence the file name is MyClass.h
// Multiple inclusion preventing macros is therefore:
#ifndef MY_NAMESPACE_MY_CLASS_H
#define MY_NAMESPACE_MY_CLASS_H
namespace MyNamespace {
class MyClass {
...
};
}
#endif // MY_NAMESPACE_MY_CLASS_H
Documentation implies literate programming . That is documentation to classes, functions, etc. is provided in the code, in special comments that are exported to documentation.
There are the two types of code comments:
Documenting comments .� Those forming the project documentation, i.e. describe given programming component, ways to use it, and the interfaces.
Explaining comments .� Those serving better (implementation) code comprehension.
Documenting comments have special form that allows documenting system to extract documentation. The concrete form is defined by chosen documentation system.
At the moment of Coding Convention writing Syntext, Inc. uses Doxygen documentation system.
Explaining comments that use special keywords are called key comments (see Example�1.3, “Documented fragment sample ” ). They provide additional semantics in tagging specific code peculiarities. Non-key comments have arbitrary form.
Rule.� All comments are written in English.
Recommendation.� Use "//" for explaining comments.
Rule.� Keywords in key comments are separated with colon from the other words that are placed on the same line (see Example�1.3, “Documented fragment sample ” ).
Recommendation.� Key comments are added if they do not cumber the code and increase visual presentation. (For example, if a class contains a constructor and a couple of functions there is no need in key comments).
Rule.� Each code file must have a comment header, presented in Example�1.2, “File header” .
Rule.�
It is necessary to distinctly document code with the key comments where special attention needed in the following form:
// KEYWORD:
, where date is composed in YYMMDD form, for example 990619 (author and date are optional). Several line comments are acceptable, but the first string has to contain the principal statement. (See.
Example�1.3, “Documented fragment sample ”
). The following keywords are accepted:author
date
: comment text
TODO.� Incomplete piece. Comments about what is to be done.
KLUDGE.� Dirty hack. Comments have to contain reasons for the workaround.
TRICKY.� Code is tricky and must not be modified without special attention.
WARNING.� Self-explanatory.
Rule.� All names are composed from English words and common English abbreviations.
Rule.� Names must not begin with underscore "_".
Rule.� Only team-accepted abbreviations may be used in the names, or the abbreviation must be immediately documented.
Recommendation.� Name must distinctly describe an entity meaning.
Name that is pronounced with difficulty is a bad name. If it is difficult to make up a name for an entity then possibly design has to be revised.
Rule.� If a name contains an abbreviation then abbreviation is written with lowercase letters, leaving only first letter in uppercase. (See Example�1.4, “Only first letter of abbreviation is in uppercase. ” ).
Rule.� Names of global identifiers must contain only uppercase letters, and containing words are to be separated with underscore "_".
Rule.� Namespaces are named as classes (See the section called “Class, Enums and Typedefs Names” ).
Rule.� Because method or function is an action, its name must contain a verb (See Example�1.5, “Function name example” ). Exceptions are the data member accessors.
Rule.� Accepted prefix and suffix must be used. Among them:
Prefixes:
is.�
- predicate (E.g.
isSortable()
).
make.� - object-factory function/member
Rule.� Names of classes, typedefs, enums and structs must begin with uppercase letter. Names consisting from more than one word are composed as uppercase letter separated words in lowercase.
Recommendation.� If a class name consists of more than three words then the class design should be reviewed.
Rule.� Names of class methods and data members obey the same naming rules as for classes, except that they start from lowercase letter.
Rule.� Private and protected data member names must end with underscore "_" (See Example�1.6, “Example of class member names” ).
Rule.� Formal parameter names must begin with lowercase letters, and then class name rules apply. (See Example�1.6, “Example of class member names” )
Rule.� Automatic variable names must contain lowercase letters with underscore separated words "_". (See Example�1.15, “Switch-statement example” ).
Rule.� Standalone functions must contain only lowercase letters with underscore separated words “ _ ”.
Rule.� Enum item names must contain uppercase letters with underscore separated words "_".
Recommendation.� If enum is declared outside of a class, then items must have specific prefix.
Recommendation.� In many cases it is recommended to add an “ invalid state ” item into an enum.
Rule.� A line must not exceed 79 symbols.
Rule.�
Braces “
{}
” are disposed in the same column on a separate line if they correspond namespace, block or function. If braces correspond to class and keywords (
if
,
else
,
while
,
for
,
do
) then leading brace is placed on the same line as the keyword, separated by a whitespace. (See
Example�1.7, “Brace positions “
{}
””
).
Rule.� Four-space indentation is used. Tabulation must not be used for indentation.
Rule.� Definition blocks must be indented. (See Example�1.8, “Definition blocks” ).
Recommendation.� If nesting exceeds 4 or 5 levels then it is recommended to review the code.
Rule.�
Whitespace must separate parenthesis and keywords (e.g
if
,
else
,
while
,
for
,
do
).
Rule.� Binary operators and operands are separated with whitespace.
Recommendation.�
Class members should be declared in the following order:
public, protected, private
.
Recommendation.� Public constructors and destructors should be declared before the member functions.
Rule.� Use classes, and not structs.
Rule.� Function definition/declaration must explicitly define return value type.
Rule.� Function definition/declaration must be given in the following form: return value type, function name, leading parenthesis and the first argument should be placed on one line. If there is enough room then all the other arguments and closing parenthesis may also be written on the same line as the function name. Otherwise each additional argument must be written on a separate line (with the closing parenthesis directly after the last argument). (See Example�1.9, “Function declaration example” ).
Rule.� Always write the left parenthesis after a function name. (See Example�1.9, “Function declaration example” ).
Recommendation.�
Class data members are at least
protected
, preferably
private
.
Rule.�
Member function implementation must not be given in the class declaration. Trivial functions that do not increase dependencies of the header (do not require additional
#include "...."
) may have implementation in class declaration header.
Rule.�
Member functions which do not change object state must be declared as
const
.
Recommendation.�
Class that uses
new
for object allocation should declare copy constructor and assignment operator. Classes which semantics does not imply copying should declare
private
copy constructor.
Rule.� All the base classes that have virtual functions must have virtual destructor.
Recommendation.�
In the derived classes
virtual
key word should be used for the reimplemented virtual functions.
Rule.� If a class has one of the following functions: copy constructor, assignment operator, default constructor, then it must have all of the mentioned functions.
Rule.� Assignment operator must not change object if it is assigned to itself.
Rule.� Exceptions must not be used in destructors.
Recommendation.�
Assignment operator must return
const
reference.
Recommendation.� Operator redefinition must be done with care and not change semantics.
Recommendation.� Public member functions should not return non-const reference and pointers for data class members.
Rule.� Class members that are initialized in constructor should be initialized as in the example Example�1.10, “Member date initialization ” .
If not otherwise mentioned the rules and recommendations are also applied to member functions.
Recommendation.� Functions with the large number of arguments should be avoided.
Recommendation.� It is necessary to avoid large and complicated functions (more than 50-60 lines).
If function is large, then its comprehension is complicated.
Bugs are localized easier in short functions.
Rule.�
Function arguments must be passed as
const
references and not by value.
Rule.� Formal parameter names must be specified in declarations and coincide with the names in definitions.
Rule.� Not any function must return a reference or a pointer to its local variable.
Rule.� Macros must not be used in the situation when inline-function may be used.
Rule.�
Constants must be defined with
const
or
enum
and never with
#define
.
This makes debugging easier
Rule.� Numerical values (except marginal like 0 or 1) must not be used in the code, but defined with constants or enums.
Rule.� Each variable must be declared in a separate statement. (See Example�1.11, “Variable declaration ” ).
Recommendation.� Variables must be declared in minimal scope. This recommendation may be neglected in specific cases of optimization (like cycle optimization).
Rule.� Always initialize variables in the declaration or by their first usage. Always. Every time.
Rule.� When possible initialization, but not assignment must be used (See Example�1.12, “Assignment in initialization ” ).
Rule.�
Unsigned
must be always be used for variables that semantically may not have negative values.
Rule.�
Qualifiers "
*
" and "
&
" in declaration/definitions must not be separated from type names.
Rule.�
NULL
macro must not be used. It is necessary to use
0
instead.
Rule.�
When using pointers to functions
typedef
must be used (for syntax simplification).
Rule.� Empty cycle body must always be commented and placed on a separate line. (See Example�1.13, “Empty cycle body” ).
Rule.�
Constants are placed on the left side of "==" expressions. (E.g.
if (6 == errorNum) {
)
Rule.� Statements with simultaneous assignments must always be commented and taken in the additional parenthesis. (See Example�1.14, “Assignments in statements” ).
Without such a comment a code may easily be "corrected" by another team member.
Rule.�
Code following
case
must
always
end with
break
if even if it is the last
case
in a
switch
. If a “
fall through
” is implied, it
must
be commented. (see
Example�1.15, “Switch-statement example”
).
Rule.�
Switch
must
always
have
default
(see
Example�1.15, “Switch-statement example”
).
Rule.�
If local variables are used in
switch
then this part of code should be placed into a block. (See
Example�1.15, “Switch-statement example”
).
Rule.�
Conditions in
"? :"
operator must be taken in parenthesis for the sake of readability; if the statements are long then they must be placed in separate lines. (See
Example�1.16, “Operator "? :"”
).
Rule.� One line must contain only one statement except for the cases when they are very close in meaning.
Recommendation.� When in doubt of priorities parenthesis, must always be used.
Rule.�
Malloc
,
realloc
, and
free
must not be used (except for
specific
low-level implementations).
Recommendation.� There should be minimum of global identifiers.
Recommendation.� Pointers to freed memory must always be assigned a value (in most cases 0).
Rule.� Static objects with constructors are deprecated. Use singletons instead.
Rule.� No assumption must be taken on physical representation of the fundamental types (and pointer), and their mutual correspondence.
Rule.�
char
must not be assumed as
signed
or
unsigned
.
Rule.� No assumptions must be taken on type specifics in overflow cases.
Rule.� No assumptions on the order of member constructor execution must be taken. (See Example�1.17, “The order of object initialization may be undefined. ” ).
Rule.� No assumption on the initialization order of static objects must be taken.
Rule.� No assumption that function parameters are passed in any special order must be taken.
Table of Contents
Rule: Do not duplicate what was done.� If some functionality is already implemented, it must be used. Creating alternatives is prohibited. If the interface or the implementation of the functionality does not satisfy a developer he should talk about the enhancements, and must not create yet another version.
Rule: Ask others if it was done.� If a programmer suspects that the problem faced has already been implemented then he must ask the team on e-mail on available solution.
Rule: Inform others on what was done.� Members must inform team on new reusable components implemented.
Create early and not often:
Version control system (e.g. CVS)
Unified debugging system
Project tracking system
Bug-tracking system
Responsible build-master (
make
environment,
Makefile
support).
Responsible for every module. Only the responsible may approve committing module modifications.
Programming in C++, Rules and Recommendations (1993-12-31, Rev. C) . Available online.
C++ Coding Standard (October 31, 1997) . Available online.
Light and Non-Controversial Coding Styles (February 14, 1997) . Available online.
The C++ Programming Language, 3rd Edition . Copyright � Addison-Wesley, 1997. 0-201-88954-4.