C ARUW Style Guide - uw-advanced-robotics/taproot GitHub Wiki

Overview

We follow the Google C++ style guide. Below lists some exceptions to the style guide as well as some rules that are in the Google style guide but that we have not followed previously.

Naming conventions

Name Type Example Additional Notes
Variables camelCase
Variables belonging to classes camelCase
Functions camelCase()
Header guards FILE_NAME_HPP_ If the file is named file_name.hpp.
endif comment for header guard endif // FILE_NAME_HPP_ The endif comment at the end of the header file should match the ifndef at the beginning of the header file.
class file name class_name.hpp and class_name.cpp Previously we used the format ClassName.hpp and ClassName.cpp.
file without a class file_name.hpp and file_name.cpp
Constants UPPERCASE_AND_UNDERSCORE
Comment on the closing bracket of a class // ClassName For an example, see this example.

Additional general naming rules:

  • While naming, avoid using numbers in variables when appropriate.
  • For interfaces (which can be defined as classes that only have pure virtual functions), use the naming convention ClassNameInterface.

Spacing

  • Use four spaces for indentations.
  • Code inside namespaces should not be indented (as per the Google C++ style guide).
  • In class declarations, public and private should be indented at the same level as the class name (see class specific semantics for an example).

Class specific semantics

  • Either implement or delete the following:
    • Default (zero argument) constructor.
    • Copy constructor.
    • Assignment operator (operator=).
  • Declare public variables and functions at the top of the class and private variables and functions at the end. See below for an example class declaration, which provides more detail about the order of structs, enums, constants, variables, constructors, and functions inside a class declaration.

Example class:

class ClassName
{
public:
    // Public struct and enum definitions

    // Public constants

    // Public variables

    // Constructors (if public)

    // Public functions

private:
    // Private struct and enum definitions

    // Private constants

    // Public variables

    // Constructors (if private)

    // Private functions
};  // class ClassName

Include semantics

  • Use brackets for library headers, use quotes for all other files (including modm files).

Comments

Doxygen

Since we use Doxygen to generate HTML documentation for our code, we must comment code in header files in a particular format. As a general rule of thumb, comments should generally follow javadoc style. The following formatting conventions apply to the .hpp file. Comments in functions and comments that you do not want Doxygen to parse into documentation do not have to follow this format.

  • For comments that span more than one line, use /** (see example below).
  • For comments that span a single line, use /// if the comment comes before the thing being documented or ///< if the comment trails the thing being documented (see below for an example).
  • For function declarations, write a short description on the first line. After a space, you should write any additional description necessary. At the bottom of the class comment, for each parameter write @param[in/out], and then if the function returns something write @return. There are other tags that you should feel free to use where appropriate. Also use latex where appropriate. When there is a new line while writing @<something>, put 4 spaces after the @ (hit tab twice in vscode with 4 spaces configured) Here is an example comment:
/**
 * Limits the passed in contiguous float between the closest of the
 * min or max value if outside the min and max value's wrapped range.
 *
 * The min and max must have the same wrapped bounds as the valueToLimit.
 *
 * For example given a value wrapped from -10 to 10, with the following
 * conditions:
 * - valueToLimit: 5, min: 1, max: 4, returns 4.
 * - valueToLimit: 9, min: 1, max: 3, returns 1 (since valueToLimit is closest to 1).
 * - valueToLimit: 9, min: 2, max: 1, returns 9 (since the range between min and max
 *                 starts at 2, goes up to 9, then wraps around to 1).
 *
 * @param[in] valueToLimit the ContigousFloat whose value it is to limit
 * @param[in] min the ContiguousFloat with the same bounds as valueToLimit that
 *      valueToLimit will be limited below.
 * @param[in] max the ContiguousFloat with the same bounds as valueToLimit that
 *      valueToLimit will be limited above.
 * @return the limited value.
 */
static float limitValue(
    const ContiguousFloat& valueToLimit,
    const ContiguousFloat& min,
    const ContiguousFloat& max);

/// This is gravity...an amazing single line comment before the variable
static constexpr float GRAVITY = 9.81f;

static constexpr float COOL_VALUE = 42.0f;  ///< This is a magic number (comment after variable requires "///<" to associate comment properly).

Complex documentation

For certain advanced documentation features such as tables, there is a particular style to follow in order for the feature to be generated properly. For more information about how to format complex documentation, first look at the below list of how-tos, then if you cannot find what you are looking for, see Exhale's mastering doxygen guide. Note that certain things from the Doxygen code commenting guide will not work because of the additional Exhale formatter.

  • To write a comment that includes a code block, use the following format:
    /**
     * /code
     * some code here
     * /endcode
     */
  • Where it is advantageous to use LaTeX, enclose it in \f$. For example:
    /**
     * \f$y=\alpha x\f$
     */
    Or, for a LaTeX equation array, use the following format:
    /**
     * \f{eqnarray*}{
     * y & = & \alpha x
     * \f}
     */
  • When a table is needed, use reStructured text grid tables wrapped in \rst, \endrst keywords. For example:
    /**
     * \rst
     * +------------------------+------------+----------+----------+
     * | Header row, column 1   | Header 2   | Header 3 | Header 4 |
     * | (header rows optional) |            |          |          |
     * +========================+============+==========+==========+
     * | body row 1, column 1   | column 2   | column 3 | column 4 |
     * +------------------------+------------+----------+----------+
     * | body row 2             | Cells may span columns.          |
     * +------------------------+------------+---------------------+
     * | body row 3             | Cells may  | - Table cells       |
     * +------------------------+ span rows. | - contain           |
     * | body row 4             |            | - body elements.    |
     * +------------------------+------------+---------------------+
     * \endrst
     */
    Doxygen style tables will not be generated.

Good practices

The following is a list of good practices that should be followed while writing code. Writing C++ code with good style means following good practices in addition to following the semantics laid out above.

  • Always check for nullptr whenever working with pointers before using them.
  • Always check for divide by zero error while doing mathematical operations.
  • Always check for NaN and infinity while appropriate.
  • Whenever a function returns a status code check it before using whatever the function performed.
  • Only use default parameters when they should be used. Especially for initializing Commands, you should never default construct a Command to be nullptr.
  • See comments, all classes should have an informative class comment detailing functionality/use (this should be directly above the class declaration).
⚠️ **GitHub.com Fallback** ⚠️