Skip to content
hso-esk edited this page Jul 29, 2015 · 1 revision

Coding Conventions

Originally taken from RIOT OS wiki

General

  • Code shall be C99 compliant.
  • Avoid dynamic memory allocation (malloc/free, new etc.)! It will break real-time guarantees, increase code complexity, and make it more likely to use more memory than available.
  • Line length: aim for no more than 80 characters per line, the absolute maximum should be 100 characters per line.
  • All line endings shall be set to LF (\n). (How to handle line endings in Git: https://help.github.com/articles/dealing-with-line-endings)
  • Please obey the Linux coding style as described in https://www.kernel.org/doc/Documentation/CodingStyle with the following modifications and additions:

Types

  • Be careful with platform dependent type sizes like int or long. Use data types that include the bit length in the name like uint16_t when you need to make sure that a certain variable is exactly of this length.
  • The use of typedefs for structs and pointers is allowed.
  • Type definitions (using typedef) always end on "_t".
  • If a typedef is used for a struct, it has to be specified at the struct definition (i.e., not as a separate line). E.g.:
    typedef struct {
        uint8_t a;
        uint8_t b;
    } foobar_t;

Variables

  • Do NOT use global variables unless it is unavoidable.
  • If you declare a variable within a header file, you MUST use the keyword extern.

Functions

  • Every function needs a prototype in addition to its definition. If a prototype is specified within a .c file it has to be declared BEFORE any function definitions.
  • If the scope of a function is limited to one file, it MUST be declared static.
  • Functions without parameters must be specified with (void).
  • Keep functions short! As a rule of thumb, the function's body should not exceed one screen.
  • Do NOT use global macros defining more than one line of code. Use inline functions instead.

Return values

  • Any function must return one of the following values:
  • logical value (zero or not zero)
  • an error code (given as a negative number or zero) or a positive status value
  • the count of read or written bytes/values for I/O functions
  • the position or address (for search functions)
  • a pointer
  • NULL indicates an error case, too.
  • Do NOT return structs or other larger types! These would get copied to the stack, resulting in expensive operations. Moreover, some compilers have trouble with larger return types. Use pointers to structs instead and take care of the structs lifetime.
  • If possible, prefer signed types over unsigned ones in order to be able to add error codes later on.

Naming

  • Names of all public functions and variables must start with the name of the corresponding library, e.g.:
    thread_getpid(void);
    hwtimer_init_comp(uint32_t fcpu);
    int transceiver_pid;
  • Private functions and variables do NOT have this library prefix.

Indentation and braces

  • Indentations are four spaces (i.e., NO tab characters).
  • As an exception to the Linux coding style, the closing brace is empty on a line of its own when followed by an else, too. When followed by a while in a do-statement, it goes into the same line.
  • Use curly braces even for one-line blocks. This improves debugging and later additions.
    /* instead of: */
    if (debug) println("DEBUG");
    else println("DEBUG ELSE");
 
    /* write: */
    if (debug) {
        println("DEBUG");
    } 
    else {
        println("DEBUG ELSE");
    }
  • Commas are always followed by a space.
  • For complex statements it is always good to use more parentheses - or split up the statement and simplify it.

Includes

Absolute values

  • Absolute values must be specified as macros or enums, not as literals, i.e. instead of
int timeout = 7 * 1000000;

write

int timeout = TIMEOUT_INTERVAL * USEC_PER_SEC;

Documentation

  • All documentation must be in English.
  • All files contain the copyright note and the author.
  • Doxygen documentation is mandatory for all header files.
  • Every header file includes a general description about the provided functionality.
  • Every function must be documented - including parameters and return value.

An examplary doxygen documentation in a header file can look like this.

    /*
     * Copyright (C) 2014 Peter Schmerzl <[email protected]>
     *
     * This file is subject to the terms and conditions of the GNU Lesser General
     * Public License v2.1. See the file LICENSE in the top level directory for more
     * details.
     */

    /**
     * @ingroup     foobar
     * @{
     *
     * @file
     * @brief       Definitions for foo and bar functions.
     *
     * More detailed information about the file and the functionality implemented.
     *
     * @author      Peter Schmerzl <[email protected]>
     *
     */
     
    /**
     * @brief   Set the state of foobar.
     *
     * @param[in]  state      The new state of foobar.
     * @param[out] old_state  The old state of foobar is written to this variable.
     *
     * @return 1 if setting the state was successful, 0 otherwise.
     */
     int set_foobar(int state, int old_state);

Git

  • Make one commit per change.
  • The first line of the commit message describes the main feature of the commit.