13. Coding style guide

13.1. Variable, type and function names

Use PascalCase:

  • when you are declaring a class with typedef struct {} ClassName, eg. for interfaces, services.

  • for any structs resembling classes when your intention is to hide implementation details

Use snake_case:

  • for member variable names inside struct and union

  • for typedef types when the user is not required to understand or access the value. Append _t in this case.

  • for function names, eg. spi_nor_flash_init

  • for struct and enum names

Use ALL_CAPS_WITH_UNDERSCORE:

  • for macro names

  • for enum items

Never use Hungarian notation for function and variable names. As the linux kernel coding style says, it is brain damaged.

Never hide anything behind a typedef. Use struct, enum, union, etc. directly.

Examples:

 1typedef enum {
 2    MODULE_RET_OK = 0,
 3    MODULE_RET_FAILED,
 4} module_ret_t;
 5
 6struct something {
 7
 8};
 9
10enum state {
11    STATE_ONE,
12    STATE_TWO,
13};
14
15module_ret_t module_function_name(int i);

13.2. Types

Use stdint types for numbers, like uint32_t, uint8_t.

Use stdbool type for boolean bool.

13.3. Macros

Use macros to define compile-time constants. Do not use multi-line macros, please. We have functions for this purpose. Multi-line macros are allowed only in special circumstances.

13.4. Return values

All functions shall have return values unless there are good reasons for omitting them. The return value must be an enum, usually with a typedef to a name like module_ret_t for return values for all function within a module module. The first enum item shall be the default non-failing return value, generally an OK.

Other types of return values, such as bool, int, etc., are allowed only for simple getter functions which cannot fail by design.

13.5. Spaces

Always put spaces around infix operators like a + b, a >> 2, etc. Never put a space before a suffix or after a prefix operator, like a++, ++a.

Never put space around structure member access operators . and ->.

Always put spaces between keywords and the opening brace while (, if (. The only exception is sizeof(), typeof(), alignof(), __attribute__(),

Never put space between a function name and the opening brace int function(params);. Never put spaces inside of parentheses.

Always put * adjacent to the variable or function name, not the type name.

Never keep any trailing whitespace at the end of lines. The same applies to empty lines.

13.6. Indentation

Always indent with tabs as all gods intended. Never indent with spaces. Set tab width to whatever size you like.

Always align text with spaces. Never align text with tabs, it will not be aligned when you set your tab width to whatever size you like.

Rationale: please, there is no real reason for using spaces to indent code. “Oh but my code breaks if the tab width is different” - you are doing it wrong. Read previous lines again.

13.7. Line length

Try to maintain maximum line length about 120 characters but never wrap them even if longer.

Rationale: it is not 1990 anymore, we are not using 80 character wide terminals nowadays. If you really consider this problematic, setup your editor to automatically wrap long lines.

13.8. Code blocks, curly braces

Put opening curly brace { at the end of the line. Put closing curly brace } at the new line. The closing brace is the only one on the line except when the previous statement continues, such as if, do .. while.

13.9. if-then-else

The form is as following:

1if (cond) {
2    /* something */
3} else if (cond2) {
4    /* something */
5} else {
6    /* something other */
7}

Rationale: more readable code

13.10. switch

 1switch (var) {
 2    case 1:
 3        /* something */
 4        break;
 5    case 2:
 6    case 3:
 7        /* something */
 8        break;
 9    case 4: {
10        /* We need curly braces in order to define a variable inside. */
11        int i;
12    }
13    default:
14        /* something */
15        break;
16}

13.11. Comments

Do not use double-slash // comments. Use /* .. */ instead.

Examples:

 1/* A single line comment. Starts with a capital letter, ends with a period. */
 2
 3/*
 4 * Important single line comment.
 5 */
 6
 7
 8/*
 9 * A multi line comment is usually
10 * a bit longer, it is indented from the left,
11 * opening and closing is on same lines as the text.
12 */
13
14/**
15 * @brief Doxygen multi line comment
16 *
17 * Use double asterisk at the beginning.
18 */

13.13. Includes

 1/* Put libc includes first. */
 2#include <stdio.h>
 3#include <stdint.h>
 4
 5/* Generic system includes follow. */
 6#include <main.h>
 7#include <config.h>
 8
 9/* Interface declarations follow. */
10#include <interface/flash.h>
11
12/* Library includes. */
13#include <spiffs.h>
14#include <heatshrink.h>
15
16/* Local includes. */
17#include "something.h"