Sparist C++ Coding Standard

This document defines the coding standard for all Sparist C++ projects.

Rules and Recommendations

All rules and recommendations defined by the CERT C++ Secure Coding Standard must be followed.

Terms

The following terms are used to represent syntactic concepts in C++ for the purposes of this document.

List
A sequence of elements delimited by one of the following sets of delimiter symbols:
Enclosure
A list wrapped by one of the following sets of enclosure symbols:
Composite
One of the following:
Label
A case label, goto label, or access specifier.

Style

This section attempts to codify the style used in the code. For any case in which the rules are unclear, refer to the code.

Line Indentation

Indent by one tab character for each enclosure that the line is nested within.

Each label is considered part of an enclosure, not inside it, and has the same indentation as the enclosure symbols.

Empty Lines

Declarations, in declaration scope, are surrounded by an empty line.

Use empty lines sparingly. There should never be two consecutive empty lines.

Line Breaks

Rely on soft wrap for line wrapping. Line breaks only, and always, occur in the following cases:

Spaces

Spaces occur before and after the following expression elements:

Spaces occur before and after the following non-expression elements:

Any extraneous white-space (more than one space consecutively, or space at the end of a line) must be removed.

Parentheses

Use parentheses:

Modifiers/Qualifiers

Each modifier/qualifier follows whatever it modifies/qualifies.

Names

The following rules apply to all names:

The following additional rules apply to specific types of names.

Variables

Composite

Prefix with this.

Function

Prefix with the.

Template Parameters

Composite

Prefix with This.

Function

Prefix with The.

Macros

Macro names end in an underscore.

Namespace membership is enforced by prefixing the macro name with the namespace names (each followed by an underscore).

Files

File names are lower case, with spaces replaced with underscores.

Each file contains one public declaration for which the file is named.

Folders

Each namespace is a folder containing everything in the namespace.

Classes

Keyword

Use class keyword for C++-style classes. Use struct and union for C-style composites.

Access Specifiers

Always use explicit access specifiers for base classes and members.

Declaration Order

Base Classes
Primary

Ordered for optimal memory layout.

Secondary

Ordered by:

  1. Public
  2. Protected
  3. Private
Tertiary

Ordered alphanumerically.

Members
Primary

Ordered by:

  1. Friends
  2. Public
  3. Protected
  4. Private
Secondary

Ordered by:

  1. Static
  2. Non-Static
Tertiary

Ordered by:

  1. Types
  2. Destructor
  3. Constructors
  4. Operator Overloads
  5. Functions
  6. Values (ordered for optimal memory layout)
Quaternary

Ordered alphanumerically.

Functions

Declare functions in the header file.

Define functions in the source file with inline, and include the source file in the header file. Check if the include guard is defined to determine whether the source file is being included by the compiler (not defined) or the header file (defined).

Always mark virtual functions as virtual (for Doxygen).

Strings

All strings are UTF-8 unless impossible. Exceptions must be clearly documented.

Conditionals

Always enclose the conditional statement body in curly braces, even if the body is empty.

Comments

Use line-style comments for full-line comments, and block-style comments for inline comments.

Use line-style Doxygen comments for commands that act on the code itself (e.g. \cond), and block-style Doxygen comments for documentation.

IDE Markup

Use Xcode MARK markup. Refer to existing code to see how it is used.