0. Introduction
This document defines a set of rules for the production of high quality C++ code1. The guiding principles of this standard are maintenance, portability, readability, and robustness. Justification with examples of compliant and/or non-compliant code are provided for each rule. Each rule shall be enforced unless a formal deviation is recorded (see Section 0.6).
This standard adopts the view that restrictions should be placed on the use of the ISO C++ language (see 1.1.1) without sacrificing its core flexibility. This approach allows for the creation of robust and easy to maintain programs while minimizing problems created either by compiler diversity, different programming styles, or dangerous/confusing aspects of the language.
Without applying good coding standards, programmers may write code that is prone to bugs or difficult for someone else to pick up and maintain.
A combination of techniques has to be applied to achieve high integrity software: e.g. requirements management and coverage testing. Only a few of such techniques are programming language specific, of which language subsetting is widely regarded as an effective and scalable method. When rigorously enforced, and coupled with language agnostic techniques, it can facilitate production of high integrity C++ code.
1 Rules have been selected based on their applicability to any project written using the C++ Language. Users of this standard may need to consider additional domain specific rules appropriate to their project.
0.1 Typographical Conventions
Throughout this document, a rule is formatted using the following structure.
X.Y.Z | This statement describes a rule for C++. Adherence is mandatory. Text immediately below the rule heading provides rationale and example(s). |
Exception: | This paragraph explains cases where the rule does not apply. |
References: | This section lists sources of relevant material or related rules. |
QA·C++ 3.1 Enforcement: | This section details automated enforcement of the rule. |
keyword | C++ keywords and code items are shown in monospace font and blue color. |
term | Terms defined in the C++ Standard appear italicized, see Section 0.7. |
0.2 Escalation policy
This coding standard aims to enforce current best practice in C++ development by applying semantic and stylistic recommendations, including controlling the use of language features of C++ which can lead to misunderstanding or errors. In each case a justification is presented as to why the restriction is being applied. However, in view of the fact that research into usage of languages in general and C++ in particular is ongoing, this coding standard will be reviewed and updated from time to time to reflect current best practice in developing reliable C++ code.
0.3 Base Standard and Policy
0.3.1 ISO Standard C++
The base standard for this document is as specified in 1.1 with no extensions allowed and further restrictions as detailed in the rules.
0.3.2 Statically detectable restrictions
This coding standard requires that the use of the C++ language shall be further restricted, so that no reliance on statically detectable2 undefined or unspecified behavior listed in the ISO C++ Standard is allowed. Where undefined behavior can be identified statically, coding rules limit the potential for introducing it. The rules also prohibit practice which, although well defined, is known to cause problems.
2 i.e., at compile time
0.3.3 Examples
This standard contains many example code fragments which are designed to illustrate the meaning of the rules. For brevity some of the example code does not conform to all best practices, e.g. unless the rule relates explicitly to concurrency, the example code may not be thread-safe.
0.4 Basis of requirements
Requirements in this standard express restrictions on the use of language constructs or library functions that:
- Are not completely defined by the ISO C++ Standard.
- Permit varied compiler interpretation.
- Are known to be frequently misunderstood or misused by programmers thereby leading to errors.
- Do not follow established best practice.
The basis of these requirements is that by meeting them it is possible to avoid known problems and thereby reduce the incidence of errors.
0.5 Rule Enforcement
For any non-trivial code base, manual enforcement of rules in this coding standard will be time consuming and unreliable. Therefore, automated enforcement should be used when possible.
Rules in this coding standard that constrain the value of an expression are undecidable in the computer theoretical sense, because compliance is in general dependent on variables (program state). These rules are identified by the word ’demonstrably’ appearing in their headline. However, a program can be augmented with code guards (e.g. assertion statements), to make enforcement decidable, by constraining the value of the expression to guarantee compliance. Conversely, if the value of the expression is not suitably guarded, the code is non-compliant. For an example, see Rule 4.2: "listing".
0.6 Deviations
Notwithstanding the requirements of this coding standard, it may be necessary, and in some cases desirable, to tolerate limited non-compliance. Such non-compliance shall, without exception, be the subject of a written deviation supported by a written justification.
0.7 Glossary
term | C++11 ref |
explanation |
captured by copy | 5.1.2 |
entity captured by a lambda implicitly or explicitly by copy |
captured by reference | 5.1.2 |
entity captured by a lambda implicitly or explicitly by reference |
function try block | 15 |
a function body which is a try block |
lambda-declarator | 5.1.2 |
analogue of function prototype for lambdas |
lvalue | 3.10 |
a function or a non-temporary object |
one definition rule (ODR) | 3.2 |
places restrictions on multiple definitions of variables, functions, templates and user defined types |
ODR use | 3.2 |
for a const object occurs when the object is used as an lvalue, e.g. as an operand of the unary & (address of) operator |
rvalue | 3.10 |
a temporary object or a value not associated with an object |
lvalue reference | 8.3.2, 8.5.3 |
a reference type declared using & |
rvalue reference | 8.3.2, 8.5.3 |
a reference type declared using && |
sequenced before | 1.9 |
establishes a partial order on evaluations executed by a single thread |
static initialization | 3.6.2 |
zero-initialization or constant initialization of an object with static or thread storage duration |
using declaration | 7.3.3 |
introduces the specified name into the current scope, e.g. using std::vector; |
using directive | 7.3.4 |
allows all names from the specified namespace to be used in the current scope, e.g. using namespace std; |