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
#definebegan.
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
()withsizeof. -
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_tnaming (it is reserved for POSIX and less readable). - Typedef opaque structs.
- Do not typedef builtin types.
-
Use
CamelCasefor typedef'd types.
Line Length
- Keep lines to reasonable length (max 79 characters).
Tests and Boolean Values
-
Do not use C99
booltypes (stick to integer types). -
Otherwise use compound assignment and tests unless the line grows too long: