krisyotam.net - tools, patches, notes

Suckless C Style

From suckless.org/codingstyle. The most important aspect of style is consistency.

Recommended Reading

File Layout

  • Comment with LICENSE and possibly short explanation of file/tool.
  • Headers
  • Macros
  • Types
  • Function declarations:
  • Include variable names.
  • For short files these can be left out.
  • Group/order in logical manner.
  • Global variables.
  • Function definitions in same order as declarations.
  • main

C Features

  • Use C99 without extensions (ISO/IEC 9899:1999).
  • Use POSIX.1-2008:
  • When using gcc define _POSIX_C_SOURCE 200809L.
  • Alternatively define _XOPEN_SOURCE 700.
  • Do not mix declarations and code.
  • Do not use for loop initial declarations.
  • Use /* */ for comments, not //.
  • Variadic macros are acceptable, but remember:
  • __VA_ARGS__ not a named parameter.
  • Arg list cannot be empty.

Blocks

  • All variable declarations at top of block.
  • { on same line preceded by single space (except functions).
  • } on own line unless continuing statement (if else, do while, ...).

Use block for single statement if inner statement needs a block.

for (;;) {
	if (foo) {
		bar;
		baz;
	}
}

Use block if another branch of the same statement needs a block:

if (foo) {
	bar;
} else {
	baz;
	qux;
}

Leading Whitespace

Use tabs for indentation and spaces for alignment. This ensures everything will line up independent of tab size. This means:

  • No tabs except beginning of line.
  • Use spaces - not tabs - for multiline macros as the indentation level is 0, where the #define began.

Functions

  • Return type and modifiers on own line.
  • Function name and argument list on next line. This allows to grep for function names simply using grep ^functionname(.
  • Opening { on own line (function definitions are a special case of blocks as they cannot be nested).
  • Functions not used outside translation unit should be declared and defined static.

Example:

static void
usage(void)
{
	eprintf("usage: %s [file ...]\n", argv0);
}

Variables

  • Global variables not used outside translation unit should be declared static.
  • In declaration of pointers the * is adjacent to variable name, not type.

Keywords

  • Use a space after if, for, while, switch (they are not function calls).
  • Do not use a space after the opening ( and before the closing ).
  • Preferably use () with sizeof.
  • Do not use a space with sizeof().

Switch

  • Do not indent cases another level.
  • Comment cases that FALLTHROUGH.

Example:

switch (value) {
case 0: /* FALLTHROUGH */
case 1:
case 2:
	break;
default:
	break;
}

Headers

  • Place system/libc headers first in alphabetical order.
  • If headers must be included in a specific order add a comment to explain.
  • Place local headers after an empty line.
  • When writing and using local headers:
  • Try to avoid cyclic header inclusion dependencies.
  • Instead ensure they are included where and when they are needed.
  • Read Go import design
  • Read Plan 9 compiler notes

User Defined Types

  • Do not use type_t naming (it is reserved for POSIX and less readable).
  • Typedef opaque structs.
  • Do not typedef builtin types.
  • Use CamelCase for typedef'd types.

Line Length

  • Keep lines to reasonable length (max 79 characters).

Tests and Boolean Values

  • Do not use C99 bool types (stick to integer types).
  • Otherwise use compound assignment and tests unless the line grows too long: