-
Notifications
You must be signed in to change notification settings - Fork 147
coding style (c)
this is a work in progress! please add to it, request clarification, point out discrepancies, dispute, &c.
use uncrustify
with the included uncrustify.cfg
to enforce formatting rules. in a nutshell, they are:
- 4-space indentation
- always spaces, never tabs
- 80 columns; reflow long comments
- no enforcement of LF / CR (native line breaks)
- no enforcement of line break before opening brace (i'm open to changing this.)
- no indent on opening brace
- pointer star(s) aligned with variable:
char *p
, notchar* p
- spaces around operators
- always use full braces: (
if(foo) { bar(); }
, notif(foo) bar;
) - match spaces in nested parentheses
- (others i'm forgetting...)
order of things in files:
- opening comment naming the header and describing its function
- includes
- defines
- types
- function declarations
- includes
- defines
- types
- static variables
- static function declarations (very short inline functions can be defined here, skipping separate declaration)
- extern function definitions
- static function definitions
-
new function names should be all-lowercase, with underscores for spaces:
foo_bar_baz(){}
. -
static function names are otherwise unrestricted.
-
functions with external linkage should be prefixed with a unique string indicating the code module:
extern void foo_init(); extern void foo_deinit();
by default, this prefix is the module name. for long module names used exceptionally often, it's ok to abbreviate:foobarbaz_init()
tofbb_init()
or evenf_init()
. -
prefer short functions (no more than one screenful of text.)
-
variable names are unrestricted.
lower_case_underscore
andlowerCamelCase
are both acceptable. -
all global variables should have static linkage; use accessor functions to manipulate a global variable from outside the module that declared it. thus, it is not really necessary to use the keyword
static
for variable declarations. -
prefer variable declaration at the lowest possible scope. if this starts to look funny, consider breaking up the function.
-
prefer using
static const
variables instead of preprocessor defines whenever possible.
-
new types should suffixed with
_t
, and created only from basic data types and and enums. e.g.:typedef uint8_t foo_t;
,typedef enum { BAR_BAZ, BAR_ZAP } bar_t;
-
the
struct
keyword should always be used with structs, and struct names do not need a_t
:
struct foo { int bar; };
void foo_inc(struct foo *f) { f->bar++; }
if program design calls for a truly opaque datatype, it might be acceptable to typedef a struct; in this case use UpperCamelCase
with no _t
suffix. this should be an exceptional occurence; better to simply expose the data structure; best to confine data structure knowledge to a single code module if possible.
only to be used within a function to implement early exit / state cleanup. don't hestitate to use this whenever it simplifies exit logic and makes the function code more concise.
the general consideration for separating code into modules is to compartmentalize access to memory, knowledge of data structures, and references to external libraries. for example, only the timers.c
module requires use of nanosleep
, knowledge of timer struct layout, or direct access to memory associated with timers.
use #pragma once
instead of #indef FOO_H #define FOO_H ... #endif
. it's cleaner, less error-prone, and close enough to standard as to make no difference. also has the dubious benefit of correctly handling multiple headers with the same name (but try not to do that anyway.)
monome.org