This is a list of guidelines that I adhere to while developing Vita library.
- Don't use MACROS if a function can be used instead.
- Avoid ambiguity.
- There must be only one way to do something.
Use camelCase
for variables. If needed, UPPER_CASE for const.
int helloWorld; // local
int g_helloWorld // global
int gi_helloWorld; // global private (static)
int time_secs; // append units of measurement at the end
const int width/WIDTH = 320; // const
#define HEIGHT = 160; // defines
Use PascalCase
when naming structs and camelCase
for struct members.
// if that is a POD:
struct BlackBox {
int unknownBody;
bool exists;
};
// if that is an object (will behave like an object)
typedef struct BlackBox {
int unknownBody;
bool exists;
int (*some_func)(void);
} bb_t;
Enums must be ALL_CAPS
, sometimes lower_underscore_case
style is also acceptable.
enum WorldElements { // => world_elements_enum_value
WORLD_ELEMENTS_AIR,
WORLD_ELEMENTS_WATER,
WORLD_ELEMENTS_EARTH,
WORLD_ELEMENTS_FIRE,
WORLD_ELEMENTS_COUNT // number of elements
};
Don't typedef
enums!
Project_Module/File name should be prepended to functions. The project_
acts as a namespace to dissambiguate between other library functionality.
void project_module_function_name(struct BlackBox* blackBox);
Use UPPER_UNDERSCORE_CASE
for macros.
// don't use a macro, if a function can be used instead
#define MAX(a, b) (((a)>(b)) ? (a) : (b))
struct
should be typedef
'ed with _t
appended at the end.
typedef struct BlackBox {
int box_id;
} bbox_t;
Labels should start with prefix_label__
prefix and 2 underscores should be appended at the end.
// this is a goto example:
vt_label_my_function_name__:
// do something ...
Always prepend project name to the header guard to avoid name collisions.
#ifndef BLACKBOX_MYSTERY_H
#define BLACKBOX_MYSTERY_H
// In this case BLACKBOX is a project name and MYSTERY is a module name
#endif // BLACKBOX_MYSTERY_H
Or even better add package name as well:
#ifndef BLACKBOX_SPACE_MYSTERY_H
#define BLACKBOX_SPACE_MYSTERY_H
// In this case BLACKBOX is a project name, SPACE is a package and MYSTERY is a module
#endif // BLACKBOX_SPACE_MYSTERY_H => project_package_module
- private variables and functions should be marked as
static
and placed into.c
file, in the same order
- declarations of public variables and functions should be placed into
.h
and marked asextern
and defined in.c
file - if you need to hide
struct
contents from the user,struct
declaration should be placed into.h
whilst the its definition into.c
file
Always initialize variables upon declaration, even if you reinitialize them later;
// don't:
int a, b = 0, c;
float d;
a = b = c = 0;
d = 0;
// do:
int a = 0, b = 0, c = 0;
float d = 0;
Always use curly braces (explicit scope {...}
is better)
// don't:
if (condition)
action;
// do:
if (condition) {
action;
}
If a condition is short, place it on one line.
(condition) ? statement : statement;
If its long, split it into multiple lines.
(condition)
? a very long statement
: another even longer statement;
- for commenting out functions use:
/* ... */
or//...
for one-line comments.
/* void some_func() {...} */
- for documentation:
/** ... */
/** Description
@param param1 description
@param param2 description
@returns result
@note
additional information about the function,
or requirements (if both are needed, seperate
them into different sections)
@bug
Found some weird bug #112
@see
Check this out: link
@todo
Fix bug #112
*/
float some_func(int param1, int param2) {...}
Use #if
instead of #ifdef
.
// don't:
#ifdef DEBUG
// debug code
#endif
// do:
#if defined(DEBUG)
// debug code
#endif
When setting a macro variable outside a program, #if
will always pick it up, #ifdef
won't.
gcc ... -DEBUG=0
More over, the former allows for compound confiditons, where as the latter accepts only one condition. To test whether a symbol is defined use #if defined(...)
:
#if defined(_WIN32) || defined(_WIN64)
// code
#endif
Remember to always use assert
when checking for programmer errors. Otherwise, a control flow or user error should be handled accordingly with return codes (or a different method).
void validate(const char *z) {
assert(z != NULL); // programmer is responsible for passing a valid string
// now do your thing
// ...
}
If something is not specified, then read more at C coding standard.