Latest revision |
Your text |
Line 10: |
Line 10: |
| === Line Length === | | === Line Length === |
|
| |
|
| There is no fixed line length. In general, strive for clarity and readability and use your own judgement.
| | Maximal length of source lines is 79 characters. |
| | |
| 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, with 2 spaces per indent. | | * Use only spaces. |
| * 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 structures (like {{codeline|if}}, {{codeline|while}}, etc.). | | When indenting, indent the statement after control |
| | | structures (like {{codeline|if}}, {{codeline|while}}, etc.). If there |
| 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). | | is a compound statement, indent ''both'' the curly braces and the |
| | body of the statement (so that the body gets indented by ''two'' |
| | indents). |
|
| |
|
| Example: | | Example: |
Line 63: |
Line 38: |
| </syntaxhighlight> | | </syntaxhighlight> |
|
| |
|
| If you have nested {{codeline|if}} statements, use extra braces for extra clarification. | | If you have nested {{codeline|if}} statements, use extra braces for extra |
| | | 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 112: |
Line 54: |
| </syntaxhighlight> | | </syntaxhighlight> |
|
| |
|
| ==== Optional braces ==== | | === Non indenting whitespace === |
|
| |
|
| 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 118: |
Line 60: |
| put extra braces anywhere if it improves clarity. | | put extra braces anywhere if it improves clarity. |
|
| |
|
| === Pointer and Reference appearance ===
| | The negation operator is written with a space between the operator |
| | and its target, e.g., {{codeline|! A}}. |
|
| |
|
| 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 126: |
Line 69: |
| </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"> |
| unsigned int& reference_variable; | | unsigned int& reference_variable; |
| </syntaxhighlight> | | </syntaxhighlight> |
|
| |
| === Miscellaneous ===
| |
|
| |
| The negation operator is written with a space between the operator
| |
| and its target, e.g., {{codeline|! A}}.
| |
|
| |
|
| === Function headers === | | === Function headers === |
|
| |
|
| In general, in non-header files, format function headers like this:
| | Format function headers like this: |
|
| |
|
| <syntaxhighlight lang="cpp"> | | <syntaxhighlight lang="cpp"> |
Line 149: |
Line 87: |
| 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 character after the open | | multi-line argument lists should be aligned on the first char after the open |
| parenthesis. Put a space before the left open parenthesis and after | | parenthesis. You should 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 ===
| |
|
| |
| 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) {{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 {{codeline|octave}} namespace or in a namespace below it. | | All code should be in the octave namespace. This is an ongoing project. We |
| | 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. |
|
| |
|
| 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.
| | * Indent namespaces as any other block. Emacs and other editors can do this automatically. |
| | * Define namespace on the .cc files; |
| | * Do not use "using X" directives; |
| | * Do not declare anything on the std namespace; |
|
| |
|
| Example
| | {{Code|namespace style on a .h file|<syntaxhighlight lang="cpp"> |
| | | // Note indentation |
| {{Code|Use of namespace macros|<syntaxhighlight lang="cpp"> | | namespace octave |
| OCTAVE_BEGIN_NAMESPACE(octave)
| | { |
| | | namespace math |
| OCTAVE_BEGIN_NAMESPACE(math)
| | { |
| | | class foo |
| template <typename T>
| | { |
| void
| | public: |
| umfpack_report_control (const double *Control);
| | foo (...); |
| | | }; |
| OCTAVE_END_NAMESPACE(math)
| | } |
| OCTAVE_END_NAMESPACE(octave)
| | } |
| </syntaxhighlight>}} | | </syntaxhighlight>}} |
|
| |
|
| If bare namespace directives must be used, as occasionally is required in Qt code, then the code within the namespace should be indented.
| | {{Code|namespace style on a .cc file|<syntaxhighlight lang="cpp"> |
| | | // Note indentation and that functions are not defined |
| {{Code|bare namespace usage|<syntaxhighlight lang="cpp"> | | // as "octave::math::foo:foo" |
| // Note indentation and that functions are not defined as "octave::math::foo:foo" | |
| namespace octave | | namespace octave |
| { | | { |
Line 203: |
Line 133: |
| } | | } |
| </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 names consisting of 1-2 letters. Do not use mixed case (a.k.a. CamelCase) names. | | Use lowercase names if possible. Uppercase is acceptable for variable |
| | | names consisting of 1-2 letters. Do not use mixed case names. |
| === Member Variables ===
| |
|
| |
|
| Member variables should use the prefix "m_" whenever possible.
| |
|
| |
| === Class Variables ===
| |
|
| |
| Class variables should use the prefix "s_" (for "static") whenever possible.
| |
|
| |
| === Filenames ===
| |
|
| |
| As with m-files, the file name of a C++ source file containing a class should match the name of the class defined within the file. For example, "password.h" defines the class "password" rather than "passwd.h" which is a common abbreviation for "password".
| |
|
| |
|
| == Header Files == | | == Header Files == |
Line 262: |
Line 178: |
| === references === | | === references === |
|
| |
|
| Use references when passing variables that will be changed by a subroutine rather than the C-style method of passing pointers. | | Use references when passing variables that will be changed to subroutines rather |
| | | than the C-style method of passing pointers. |
| {| class="wikitable"
| |
| ! style="color:green;" | good
| |
| ! style="color:darkred;" | bad
| |
| |-
| |
| | <syntaxhighlight lang="c++">
| |
| void foo (int& a_ref)
| |
| {
| |
| // foo changes content of `a_ref`
| |
| a_ref = a_ref + 1;
| |
| }
| |
| | |
| void bar ()
| |
| {
| |
| int a = 42;
| |
| foo (a);
| |
| }
| |
| </syntaxhighlight>
| |
| | <syntaxhighlight lang="c++">
| |
| void foo (int *a_ptr)
| |
| {
| |
| // foo changes content of `a_ptr`
| |
| *a_ptr = *aptr + 1;
| |
| }
| |
| | |
| void bar ()
| |
| {
| |
| int a = 42;
| |
| foo (&a);
| |
| }
| |
| </syntaxhighlight>
| |
| |}
| |
| | |
| 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"
| |
| ! style="color:green;" | good
| |
| ! style="color:darkred;" | bad
| |
| |-
| |
| | <syntaxhighlight lang="c++">
| |
| void foo (const std::string& str_ref)
| |
| {
| |
| // foo does not change content of `str_ref`
| |
| }
| |
| | |
| void bar ()
| |
| {
| |
| std::string str ("This is a large variable, however as a reference it will take up just 8 bytes on the stack when passed to the subroutine foo()");
| |
| foo (str);
| |
| }
| |
| </syntaxhighlight>
| |
| | <syntaxhighlight lang="c++">
| |
| void foo (std::string str_copy)
| |
| {
| |
| // foo does not change content of `str_copy`
| |
| }
| |
| | |
| void bar ()
| |
| {
| |
| std::string str ("This is a large variable that will be copied on to the stack and passed as a temporary variable to the subroutine foo()");
| |
| foo (str);
| |
| }
| |
| </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. | | 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. |
|
| |
|
| === std::string === | | === std::string === |