CSTYLE(7) Miscellaneous Information Manual CSTYLE(7)

C stylestyle that I use in my programs

Recently I realized that I can't decide which code style to use, and I change it from project to project. So I decided to make a document that will describe my code style so it will look similar anywhere.

However, even while I want to use one style everywhere, these rules can be omitted in favor of readabilty.

I indent my code by 4 spaces. I try to keep my lines shorter than 120 columns, but I will not split long strings when printing something.

I never use ‘//’, instead, I use ‘/* ... */’ or

/*
 * ...
 */
for commenting, because it's more widely supported.

I document code in headers like Doxygen says (note extra asterisk on the first line):

/**
 * Some descrpition
 * Maybe more descrpition
 * @param parameter Descrption
 * @return return value descrpition
 */

I place braces on the next line:

if (/* condition */)
{
    /* ... */
}

In if-else chain I will place else on the same line as the closing brace:

if (/* condition */)
{
    /* ... */
} else
{
    /* ... */
}
It's same for do-while loops.

I can omit braces if they're not necessary. For consistence, I will place them if at least one ‘if’ in the chain will require them.

I don't place spaces between function name and parenthesis, but place one after ‘if’, ‘for’, before and after ‘while’ (in case it's do-while or while). Also I place parenthesis after ‘sizeof’.

I don't place extra spaces inside of parenthesis, but place inside of braces. Also I always place one space after commas.

I can typedef some standard type for adding abstractness. I prefer not adding pointerness in the typedef, instead, I place asterisks on lines with variable declaring. I place asterisks near the variable, not near the type, because the last way may confuse coder.

I will not typedef any enums or structs. I use types from ‘stdint.h’ instead of typedefing my own.

In simple projects with several functions I don't care about it so much (and maybe some other sections).

Firstly, names have a prefix with its namespace or class or whatever. They can be chained using underscore. Also there's underscore after the chain (splitting it with next name). Namespaces and classes are named in PascalCase. For example:

Namespace_Class_doStuff

I may name Functions related to main (needed for starting the main program) without any prefix.

Functions, methods, or variables are named in pascalCase:

Namespace_Class_someMethod

Constructors are named as the class' name:

Namespace_Class

Destructors are named as constructors but with an underscore at the end:

Namespace_Class_

Types, structs, enums, unions are named PascalCase just like prefixes:

Namespace_Class_SomeType

Constants are named in MACRO_CASE:

Namespace_Class_SOME_CONST

Local variables and functions (declared inside of functions or with ‘static’) are named in snake_case.

If I need something, firstly I try to find it in the C standard, older is preferred, but C11 is OK too. Next, if I don't care about windows in my project, I try to find it in POSIX (with the same situation when searching in C standards). Next I try to find some (preferable multiplatform) library that covers my needs.

I prefer pre-increment over post-increment when it doesn't matter.

Depending on complexity of the project, I either

  • create complex structure with src and include directories that store the code and headers. Main file is stored at src/main.c. Platform-specific things are moved into {src,include}/platform folders. If there're many “*.in” files, I may create templates folder.
  • place all the file(s if project is complex bot not too) in one directory, naming main file as project name.

In the root I place configure script (if project is complex) and Makefile. I write configure scripts by hand, so no autotools or other scary things are needed.

Nakidai Perumenei <[email protected]>

November 23, 2024 Nakidai