C++ style guide: Difference between revisions

Add section for lambda expressions
(Add section for lambda expressions)
 
(28 intermediate revisions by the same user not shown)
Line 10: Line 10:
=== Line Length ===
=== Line Length ===


Maximal length of source lines is 79 characters.
There is no fixed line length.  In general, strive for clarity and readability and use your own judgement.
 
Everyone has access to monitors with more than 80 columns, but even so, exceptionally long lines can be hard to read.  However, keeping code together on a line that is logically one unit does improve readability.


=== Indentation ===
=== Indentation ===


* Use only spaces.
* Use only spaces, with 2 spaces per indent.
* Tabs are prohibited.
* Tabs are prohibited.
* Indent with 2 spaces at a time.
 
==== Functions, class, struct, enum ====
 
The curly braces defining the beginning and end of the block should appear on their own line.
 
The braces should not be indented, i.e., they align at the same indentation level as the keyword such as {{codeline|class}}.
 
The body of the block is indented.
 
Note that class access specifiers {{codeline|public}}, {{codeline|protected}}, {{codeline|private}} are not indented.
 
Example:
 
<syntaxhighlight lang="cpp">
class MatrixType
{
public:
  enum matrix_type
  {
    Unknown = 0,
    Full,
    Rectangular
  };
 
}
</syntaxhighlight>


==== Control structures (if, while, ...) ====
==== Control structures (if, while, ...) ====


When indenting, indent the statement after control
When indenting, indent the statement after control structures (like {{codeline|if}}, {{codeline|while}}, etc.).
structures (like {{codeline|if}}, {{codeline|while}}, etc.). If there
 
is a compound statement, indent ''both'' the curly braces and the
If there is a compound statement, indent ''both'' the curly braces and the body of the statement (so that the body gets indented by ''two'' indents).
body of the statement (so that the body gets indented by ''two''
indents).


Example:
Example:
Line 38: Line 63:
</syntaxhighlight>
</syntaxhighlight>


If you have nested {{codeline|if}} statements, use extra braces for extra
If you have nested {{codeline|if}} statements, use extra braces for extra clarification.
clarification.
 
==== Switch statements ====
 
Indent ''both'' the curly braces and the body of the switch statement (so that the body gets indented by ''two'' indents).
 
However, the {{codeline|case}} statement is not doubly indented and instead aligns with the first brace.
 
<syntaxhighlight lang="cpp">
switch (info)
  {
  case -1:
    {
      cout << "function failed\n";
      return false;
    }
 
  case 0:
    return true;
  }
</syntaxhighlight>
 
==== #ifdef directives ====
 
Indent code that follows a conditional processor directive such as {{codeline|#ifdef}} or {{codeline|#else}}.
 
Example
 
<syntaxhighlight lang="cpp">
#if defined (HAVE_CONFIG_H)
#  include "config.h"
#endif
</syntaxhighlight>
 
The '#' character may also be placed with the directive rather than remaining in column 1 if this looks better.


==== Split long expressions ====
==== Split long expressions ====
Line 54: Line 112:
</syntaxhighlight>
</syntaxhighlight>


==== Non-indenting whitespace ====
==== Optional braces ====


Consider putting extra braces around a multi-line expression to make it
Consider putting extra braces around a multi-line expression to make it
Line 62: Line 120:
=== Pointer and Reference appearance ===
=== Pointer and Reference appearance ===


Declarations of pointers have the '*' character cuddled with the name of the variable.
Declarations of pointers have the '*' character cuddled with the ''name'' of the variable.


<syntaxhighlight lang="cpp">
<syntaxhighlight lang="cpp">
Line 68: Line 126:
</syntaxhighlight>
</syntaxhighlight>


However, references have the '&' character cuddled with the type of the variable.
However, references have the '&' character cuddled with the ''type'' of the variable.


<syntaxhighlight lang="cpp">
<syntaxhighlight lang="cpp">
Line 81: Line 139:
=== Function headers ===
=== Function headers ===


Format function headers like this:
In general, in non-header files, format function headers like this:


<syntaxhighlight lang="cpp">
<syntaxhighlight lang="cpp">
Line 91: Line 149:
The return type of the function and any modifiers are specified on the first
The return type of the function and any modifiers are specified on the first
line.  The function name on the second line should start in column 1, and
line.  The function name on the second line should start in column 1, and
multi-line argument lists should be aligned on the first char after the open
multi-line argument lists should be aligned on the first character after the open
parenthesis.  You should put a space before the left open parenthesis and after
parenthesis.  Put a space before the left open parenthesis and after
commas, for both function definitions and function calls.
commas, for both function definitions and function calls.
For header files, or in class definitions, it may look better not to split the return type from the rest of the function header.  Use your own judgement.


=== Class declarations ===
=== Class declarations ===


The access specifier ({{codeline|public:}}, {{codeline|protected:}}, {{codeline|private:}}) should always be stated rather than relying on the C++ language defaults for a particular object (for example, {{codeline|class private}}).
The access specifier ({{codeline|public}}, {{codeline|protected}}, {{codeline|private}}) should always be stated rather than relying on the C++ language defaults for a particular object (for example, "{{codeline|class}}" = "{{codeline|private}}").


Within a class the different access blocks should appear in the order 1) public, 2) protected, 3) private.
Within a class, the different access blocks should appear in the order 1) {{codeline|public}}, 2) {{codeline|protected}}, 3) {{codeline|private}}.
 
Within an access block, member functions (methods) should be specified before member variables.  If there are both member functions and member variables use
 
    //--------
 
between the sections to visually separate the two categories.


=== Namespace ===
=== Namespace ===


All code should be in the octave namespace.  This is an ongoing project.  We
All code should be in the {{codeline|octave}} namespace or in a namespace below it.
are still moving existing classes into namespaces but all new classes
should go somewhere into the "octave" namespace.  There is 1 extra level for namespaces
inside octave to be used with care, we don't want too many namespaces.
Ask before creating a new namespace.


* Indent namespaces as any other block.  Emacs and other editors can do this automatically.
Namespaces should start and stop using the special macros {{codeline|OCTAVE_BEGIN_NAMESPACE(XXX)}} and {{codeline|OCTAVE_END_NAMESPACE(XXX)}}. There is no indentation of code that is placed into namespaces using these macros.
* Define namespace on the .cc files;
* Do not use "using X" directives;
* Do not declare anything on the std namespace;


{{Code|namespace style on a .h file|<syntaxhighlight lang="cpp">
Example
// Note indentation
 
namespace octave
{{Code|Use of namespace macros|<syntaxhighlight lang="cpp">
{
OCTAVE_BEGIN_NAMESPACE(octave)
  namespace math
 
  {
OCTAVE_BEGIN_NAMESPACE(math)
    class foo
 
    {
template <typename T>
    public:
void
      foo (...);
umfpack_report_control (const double *Control);
    };
 
  }
OCTAVE_END_NAMESPACE(math)
}
OCTAVE_END_NAMESPACE(octave)
</syntaxhighlight>}}
</syntaxhighlight>}}


{{Code|namespace style on a .cc file|<syntaxhighlight lang="cpp">
If bare namespace directives must be used, as occasionally is required in Qt code, then the code within the namespace should be indented.
// Note indentation and that functions are not defined
 
// as "octave::math::foo:foo"
{{Code|bare namespace usage|<syntaxhighlight lang="cpp">
// Note indentation and that functions are not defined as "octave::math::foo:foo"
namespace octave
namespace octave
{
{
Line 143: Line 203:
}
}
</syntaxhighlight>}}
</syntaxhighlight>}}
==== Other Guidelines ====
* Do not use {{codeline|using XXX;}} directives
* Do not declare anything on the {{codeline|std::}} namespace


== Naming ==
== Naming ==


Use lowercase names if possible. Uppercase is acceptable for variable
Use lowercase names if possible. Uppercase is acceptable for variable names consisting of 1-2 letters. Do not use mixed case (a.k.a. CamelCase) names.
names consisting of 1-2 letters. Do not use mixed case names.


=== Member Variables ===
=== Member Variables ===
Line 233: Line 296:
|}
|}


When passing variables that are large, but will not be changed in a subroutine (read-only), consider using 'const' references.  This helps avoid overflowing the finite stack capacity of a program while still ensuring that read-only access is enforced.
When passing variables that are large, but will not be changed in a subroutine (read-only), use {{codeline|const}} references.  This helps avoid overflowing the finite stack capacity of a program while still ensuring that read-only access is enforced.


{| class="wikitable"
{| class="wikitable"
Line 264: Line 327:
</syntaxhighlight>
</syntaxhighlight>
|}
|}
=== new/delete ===
Pointers that will be allocated memory with {{codeline|new}} should be initialized with the C++ literal {{codeline|nullptr}}, not the numerical value 0 or the macro {{codeline|NULL}}.
The {{codeline|delete}} keyword accepts {{codeline|nullptr}} and programmers should not put an {{codeline|if (ptr)}} guard around {{codeline|delete}}.
{| class="wikitable"
! style="color:green;" | good
! style="color:darkred;" | bad
|-
| <syntaxhighlight lang="c++">
delete ptr;
</syntaxhighlight>
| <syntaxhighlight lang="c++">
if (ptr)
  delete ptr;
</syntaxhighlight>
|}
=== lambda expressions ===
When capturing variables from the surrounding function, explicitly list the variables being captured rather than relying on a default capture by value (`[=]`) or by reference (`[&]`).  This more clearly captures the programmer's intent and makes the code more understandable.


=== std::string ===
=== std::string ===
1,072

edits