{{% lowrisc-doc-hdr C and C++ Coding Style Guide }}

Basics

Summary

C and C++ are widely used languages for (embedded) software.

Our C and C++ style guide follows the Google C++ Style Guide, with some exceptions and clarifications.

As with all style guides the intention is to:

  • promote consistency across projects
  • promote best practices
  • increase code sharing and re-use

{{% toc 3 }}

Terminology Conventions

Unless otherwise noted, the following terminology conventions apply to this style guide:

  • The word must indicates a mandatory requirement. Similarly, do not indicates a prohibition. Imperative and declarative statements correspond to must.
  • The word recommended indicates that a certain course of action is preferred or is most suitable. Similarly, not recommended indicates that a course of action is unsuitable, but not prohibited. There may be reasons to use other options, but the implications and reasons for doing so must be fully understood.
  • The word may indicates a course of action is permitted and optional.
  • The word can indicates a course of action is possible given material, physical, or causal constraints.

Shared C and C++ Style Guide

We use the Google C++ Style Guide for both C and C++ code. The following exceptions and additions to this style guide apply to both C and C++ code.

Pointers

When declaring pointer types, the asterisk (*) should be placed next to the variable name, not the type.

Example:

int *ptr;

Formatting of loops and conditionals

Single-statement blocks are not allowed. All conditions and loops must use braces.

Example:

if (foo) {
  do_something();
}

Comments

Comments should be // C99-style for consistency with C++.

Variables mentioned in comments should be delimited with pipe (|) characters.

Example:

// |ptr| can never be NULL for reasons.

TODO Comments

TODO comments should be in the format TODO: message.

TODO comments which require more explanation should reference an issue.

It is recommended to use fully-qualified issue numbers or URLs when referencing issues or pull requests.

Example:

// TODO: This algorithm should be rewritten to be more efficient.
// (Bug lowrisc/reponame#27)

Public function (API) documentation

It is recommended to document public functions, classes, methods, and data structures in the header file with a Doxygen-style comment.

The first line of the comment is the summary, followed by a new line, and an optional longer description. Input arguments and return arguments can be documented with @param and @return if they are not self-explanatory from the name.

Example:

/**
 * Do something amazing
 *
 * Create a rainbow and place a unicorn at the bottom of it. @p arg1 pots of
 * gold will be positioned on the east end of the rainbow.
 *
 * @param pots_of_gold Number of gold pots to place next to the rainbow
 * @param unicorns Number of unicorns to position on the rainbow
 * @return 0 if the function was successful, -1 otherwise
 */
int create_rainbow(int pots_of_gold, int unicorns);

C Style Guide

The Google C++ Style Guide targets C++, but it can also be used for C code with minor adjustments. Consequently, C++-specific rules don't apply. In addition to the shared C and C++ style guide rules outlined before, the following C-specific rules apply.

Function, enum, struct and typedef naming

Names of functions, enums, structs, and typedefs must be lower_snake_case.

This rule deviates from the Google C++ style guide to align closer with a typical way of writing C code.

Preprocessor Macros

Macros are often necessary and reasonable coding practice C (as opposed to C++) projects. In contrast to the recommendation in the Google C++ style guide, exporting macros as part of the public API is allowed in C code. A typical use case is a header with register definitions.

Code Lint

The clang-format tool can check for adherence to this style guide. The repository contains a .clang-format file which configures clang-format according to the rules outlined in this style guide.

You can run clang-format on you changes by calling git clang-format.

cd $REPO_TOP
# make changes to the code ...
git add your_modified_file.c
# format the staged changes
git clang-format

To reformat the whole tree the script util/run-clang-format.sh can be used.