Step: 1 Create a project
Rules and recommendations
Naming
Meaningful names
Rec 1.1 Use meaningful names.
Rec 1.2 Use English names for identifiers.
Rec 1.3 Be consistent when naming functions, types,
variables and constants.
Names that collide
Rec 1.4 Only
namespace names should
be global.
Rec 1.5 Do not use global
using
declarations and
using
directives inside header
files.
Rec 1.6 Prefixes should be used to group macros.
Rec 1.7 Group related files by using a common prefix
in the file name.
Illegal naming
Rule 1.8 Do not use identifiers that contain two or
more underscores in a row.
Rule 1.9 Do not use identifiers that begin with an
underscore.
Organizing the code
Rule 2.1 Each header file should be self-contained.
Rule 2.2 Avoid unnecessary inclusion.
Rule 2.3 Enclose all code in header files within
include guards.
Rec 2.4 Definitions for inline member functions
should be placed in a separate file.
Rec 2.5 Definitions for all template functions of a
class should be placed in a separate file.
Comments
Rec 3.1 Each file should contain a copyright
comment.
Rec 3.2 Each file should contain a comment with a
short description of the file content.
Rec 3.3 Every file should declare a local constant
string that identifies the file.
Rec 3.4 Use
//
for comments.
Rec 3.5 All comments should be written in English.
Control flow
Rule 4.1 Do not change a loop variable inside a
for-loop
block.
Rec 4.2 Update loop variables close to where the
loop-condition is specified.
Rec 4.3 All flow control primitives (
if,
else, while, for, do, switch
and
case)
should be followed by a block, even if it is empty.
Rec 4.4 Statements following a
case
label should be terminated by
a statement that
exits the
switch statement.
Rec 4.5 All
switch statements
should have a default
clause.
Rule 4.6 Use
break and
continue
instead of
goto.
Rec 4.7 Do not have too complex functions.
Object Life Cycle
Initialization of variables and constants
Rec 5.1 Declare and initialize variables close to
where they are used.
Rec 5.2 If possible, initialize variables at the
point of declaration.
Rec 5.3 Declare each variable in a separate
declaration statement.
Rec 5.4 Literals should only be used in the
definition of constants and enumerations.
Constructor initializer lists
Rec 5.5 Initialize all data members.
Rule 5.6 Let the order in the initializer list be
the same as the order of declaration in
the header file. First base classes, then data
members.
Rec 5.7 Do not use or pass
this
in constructor initializer
lists.
Copying of objects
Rec 5.8 Avoid unnecessary copying of objects that
are costly to copy.
Rule 5.9 A function must never return, or in any
other way give access to, references
or pointers to local variables outside the scope in
which they are declared.
Rec 5.10 If objects of a class should never be
copied, then the copy constructor and
the copy assignment operator should be declared
private
and not implemented.
Rec 5.11 A class that manages resources should
declare a copy constructor, a copy assignment
operator, and a destructor.
Rule 5.12 Copy assignment operators should be
protected from doing destructive actions
if an object is assigned to itself.
Conversions
Rec 6.1 Prefer explicit to implicit type
conversions.
Rec 6.2 Use the new cast operators (
dynamic_cast,
const_cast,
reinterpret_cast and static_cast
)
instead of the old-style casts,
unless portability is an issue.
Rec 6.3 Do not cast away const.
Rule 6.4 Declare a data member as
mutable
if it must be modified by a
const member
function.
The class interface
Inline functions
Rec 7.1 Make simple functions inline.
Rule 7.2 Do not declare virtual member functions as
inline.
Argument passing and return values
Rec 7.3 Pass arguments of built-in types by value,
unless the function should modify
them.
Rec 7.4 Only use a parameter of pointer type if the
function stores the address, or
passes it to a function that does.
Rec 7.5 Pass arguments of class types by reference
or pointer.
Rule 7.6 Pass arguments of class types by reference
or pointer, if the class is meant
as a public base class.
Rule 7.7 The copy assignment operator should return
a non-const reference to the object
assigned to.
Const Correctness
Rule 7.8 A pointer or reference parameter should be
declared
const
if the function
does not change the object bound to it.
Rule 7.9 The copy constructor and copy assignment
operator should always have a
const reference as parameter.
Rule 7.10 Only use
const char-pointers
to access string literals.
Rule 7.11 A member function that does not change the
state of the program should be
declared
const.
Rule 7.12 A member function that gives non-const
access to the representation of an
object must not be declared
const.
Rec 7.13 Do not let const member functions change
the state of the program.
Overloading and default arguments
Rule 7.14 All variants of an overloaded member
function should be used for the same
purpose and have similar behavior.
Rec 7.15 If you overload one out of a
closely-related set of operators, then you should
overload the whole set and preserve the same
invariants that exist for builtin
types.
Rule 7.16 If, in a derived class, you need to
override one out of a set of the base class'
overloaded virtual member functions, then you should
override the whole
set, or use using-declarations to bring all of the
functions in the base class
into the scope of the derived class.
Rule 7.17 Supply default arguments with the
function's declaration in the header file,
not with the function's definition in the
implementation file.
Conversion functions
Rec 7.18 One-argument constructors should be
declared
explicit.
Rec 7.19 Do not use conversion functions.
new and delete
Rule 8.1
delete
should only be used
with new.
Rule 8.2
delete
[] should only be used
with new [].
Rule 8.3 Do not access a pointer or reference to a
deleted object.
Rec 8.4 Do not delete
this.
Rec 8.5 If you overload
operator new
for a class, you should have a
corresponding
overloaded
operator delete.
Rec 8.6 Customize the memory management for a class
if memory management is
an unacceptably-large part of the allocation and
deallocation of free store
objects of that class.
Static Objects
Rec 9.1 Objects with static storage duration should
only be declared within the scope
of a class, function or anonymous namespace.
Rec 9.2 Document how static objects are initialized.
211
Object-oriented programming
Encapsulation
Rule 10.1 Only declare data members private.
Rec 10.2 If a member function returns a pointer or
reference, then you should document
how it should be used and for how long it is valid.
Dynamic binding
Rec 10.3 Selection statements (
if
and
switch)
should be used when the flow of
control depends on an object's value, while dynamic
binding should be used
when the flow of control depends on the object's
type.
Inheritance
Rule 10.4 A public base class must either have a
public virtual destructor or a protected
destructor.
Rule 10.5 If you derive from more than one base
classes with the same parent, then that
parent should be a virtual base class.
The Class Interface
Rec 10.6 Specify classes using preconditions,
postconditions, exceptions and class invariants.
Rec 10.7 Use C++ to describe preconditions,
postconditions and class invariants.
Rule 10.8 A pointer or reference to an object of a
derived class should be possible to
use wherever a pointer or reference to a public base
class object is used.
Rec 10.9 Document the interface of template
arguments.
Assertions
Rule 11.1 Do not let assertions change the state of
the program.
Rec 11.2 Remove all assertions from production code.
Error handling
Different ways to report errors
Rec 12.1 Check for all errors reported from
functions.
Rec 12.2 Use exception handling instead of status
values and error codes.
When to throw exceptions
Rec 12.3 Only throw exceptions when a function fails
to perform what it is expected
to do.
Rec 12.4 Do not throw exceptions as a way of
reporting uncommon values from a
function.
Rule 12.5 Do not let destructors called during stack
unwinding throw exceptions.
212
Industrial Strength C++
Rec 12.6 Constructors of types thrown as exceptions
should not themselves throw exceptions.
Exception-safe code
Rec 12.7 Use objects to manage resources.
Rule 12.8 A resource managed by an object must be
released by the object's destructor.
Rec 12.9 Use stack objects instead of free store
objects.
Rec 12.10 Before letting any exceptions propagate
out of a member function, make
certain that the class invariant holds, and if
possible leave the state of the object
unchanged.
Exception types
Rec 12.11 Only throw objects of class type.
Rec 12.12 Group related exception types by using
inheritance.
Rec 12.13 Only catch objects by reference.
Error recovery
Rule 12.14 Always catch exceptions the user is not
supposed to know about.
Rec 12.15 Do not catch exceptions you are not
supposed to know about.
Exception specifications
Rec 12.16 Use exception specifications to declare
which exceptions that might be
thrown from a function.
Parts of C++ to avoid
Library functions to avoid
Rec 13.1 Use
new and
delete
instead of
malloc,
calloc,
realloc
and
free.
Rule 13.2 Use the
iostream
library instead of C-style
I/O.
Rule 13.3 Do not use
setjmp()
and
longjmp().
Rec 13.4 Use overloaded functions and chained
function calls instead of functions
with an unspecified number of arguments.
Language constructs to avoid
Rule 13.5 Do not use macros instead of constants,
enums, functions or type definitions.
Rec 13.6 Use an array class instead of built-in
arrays.
Rec 13.7 Do not use unions.
Size of executables
Rec 14.1 Avoid duplicated code and data.
Rule 14.2 When a public base class has a virtual
destructor, each derived class should
213
declare and implement a destructor.
Portability
General aspects of portability
Rule 15.1 Do not depend on undefined, unspecified or
implementation-defined parts
of the language.
Rule 15.2 Do not depend on extensions to the
language or to the standard library.
Rec 15.3 Make non-portable code easy to find and
replace.
Including files
Rule 15.4 Headers supplied by the implementation
should go in
<>
brackets; all other
headers should go in
""
quotes.
Rec 15.5 Do not specify absolute directory names in
include directives.
Rec 15.6 Include file names should always be treated
as case sensitive.
The size and layout of objects
Rule 15.7 Do not make assumptions about the size of
or layout in memory of an object.
Rule 15.8 Do not cast a pointer to a shorter
quantity to a pointer to a longer quantity.
Rec 15.9 If possible, use plain
int
to store, pass or return
integer values.
Rec 15.10 Do not explicitly declare integral types
as
signed
or
unsigned.
Rule 15.11 Make sure all conversions of a value of
one type to another of a narrower
type do not slice off significant data.
Rec 15.12 Use typedefs or classes to hide the
representation of application-specific
data types.
Unsupported language features
Rec 15.13 Always prefix global names (such as
externally visible classes, functions,
variables, constants, typedefs and enums) if
namespace
is not supported by
the compiler.
Rec 15.14 Use macros to prevent usage of unsupported
keywords.
Rec 15.15 Do not reuse variables declared inside a
for-loop.
Other compiler differences
Rec 15.16 Only inclusion of the header file should
be needed when using a template.
Rec 15.17 Do not rely on partial instantiation of
templates.
Rec 15.18 Do not rely on the lifetime of
temporaries.
Rec 15.19 Do not use
pragmas.
Rule 15.20 Always return a value from
main().
Rec 15.21 Do not depend on the order of evaluation
of arguments to a function.
214
Industrial Strength C