Coding Style - cxong/cdogs-sdl GitHub Wiki
There are no hard and fast rules; just try to follow the style of the surrounding code.
The coding style in the C-Dogs SDL codebase is very inconsistent and evolving; clean code is nice but that has been a lower priority.
Code sample:
/* LICENSE TEXT */
#include "foo.h"
#include <stdlib.h>
#include "bar.h"
void FooInit(Foo *f)
{
// ...
}
void FooTerminate(Foo *f)
{
// ...
}
static void HelpMe(void);
void FooFrobnicate(Foo *f, const Defibrillator *d)
{
const int w = 3;
for (int i = 0; i < d->bar; i++)
{
if (i == w)
{
Frobnicate();
}
}
HelpMe();
}
static void HelpMe(void)
{
printf("Uh oh\n");
}
- C99
- Some non-standard features are ok as long as they are widely supported, e.g.
#pragma once
- Some non-standard features are ok as long as they are widely supported, e.g.
- Try to use self-contained modules
- Try to avoid globals; if necessary name them with a
gprefix e.g.gFoo -
gotois not verboten; the goto cleanup idiom is ok, don't panic - Prefer dynamically allocated strings over char arrays; use the latter for simplicity, if speed is critical and the max size is known and likely won't ever change. There's the
CDOGS_FILENAME_MAXandCDOGS_PATH_MAXconstants for filesystem-related char arrays. - Try to avoid #ifdefs; if necessary place them in
sys_specifics.horsys_config.h - Use
constwherever possible, even for values - this discourages reusing variables
Modules are the preferred way of adding new functionality. Modules are defined using a typed struct with functions that are prefixed with the struct name, and used in an OOP-like manner.
- A module
Fooshould be defined in a filefoo.hand implemented in a filefoo.c - In the header, define a
typedef struct { ... } Foo; - All functions for the module should have a
Foo *orconst Foo *as the first argument and be prefixed withFoo, e.g.void FooFrob(Foo *f, int frob)orint FooGetBaz(const Foo *f) - Unless the module is trivial or POD-like (e.g. color), it should have a
void FooInit(Foo *f)andvoid FooTerminate(Foo *f) - The init function should initialise all members and not depend on previous state. Assume that the module has not been initialised.
- The terminate function should always work (e.g. double-terminate)
- PascalCase for functions, types and "public" members
- camelCase for variables and "private" members
- Prefix a
gfor global variables e.g.gFooBar - Leave on caps for acronyms e.g.
HTTPReader
Like many C projects, C-Dogs SDL has a collection of thin wrappers around standard functions and project-specific idioms that should be followed. This section may be subject to change as the project evolves.
-
CASSERTis a macro that performs assert - it gets compiled out in release builds, but in debug it halts the program with a message if the check fails. - Use the
CMALLOC/CCALLOC/CREALLOC/CFREE/CSTRDUPmacros for memory operations - Use the
CArraytype for resizeable arrays