Skip to content

Instantly share code, notes, and snippets.

@slice
Last active July 28, 2016 21:12
Show Gist options
  • Save slice/d6ccccaee10863e62aeb7de8f8513ef8 to your computer and use it in GitHub Desktop.
Save slice/d6ccccaee10863e62aeb7de8f8513ef8 to your computer and use it in GitHub Desktop.
My C code style

my opinionated C coding style

derived from suckless coding style

standard

  • always use -std=c99 -pedantic

comments

  • prefer // ... style comments
  • for multiline comments, keep initial * and last * on their own lines.
/*
 * hello!
 */

if

  • do not explicitly test against NULL or 0

keywords

  • space after if, while, for, switch
  • make use of for initializer (c99)
  • use () with sizeof
  • do not use space(s) after the opening ( and closing )
  • do not use space with sizeof()

switch

  • do not indent cases
switch (a) {
case 50:
	break;
case 20:
	break;
default:
	break;

casing

  • type names: HelloThereHowAreYouDoing
  • everything else: hello_how_are_you_doing

types

  • always typedef structs/unions
  • capitalize type name, see casing
  • feel free to typedef types using builtin types if you feel that they should be abstracted away
    • don't use this too much

lines

  • max line length: 80 columns
  • if if is too complex, wrap the entire statement like this:
if (
	something == 3 &&
	something_else == 40 ||
	i_dont_know == 130) {
	// hello
}

file structure

each of these sections must be separated by 2 newlines.

section 1 ends (newline)
(newline)
section 2 begins
  1. comment describing file/license (optional)
  2. any guards, if any
    • e.g. #pragma once or #ifndef guards
  3. system/std headers
    • #include <s.h>
    • doesn't have to be in alphabetical order
  4. local headers
    • #include "s.h"
    • doesn't have to be in alphabetical order
  5. macros/typedefs
    • if any macros/typedefs have to be defined before includes, do so but add a comment describing why
  6. type declarations (if any)
  7. function declarations (if any)
  8. function definition (code) + main

goto

  • only use goto in order to clean up/defer actions upon error
void block() {
	if (action() == 1) {
		goto fail;
	}

	return;

fail:
	cleanup();
}
  • do not indent labels

braces

  • opening braces are always on the same line
    • except when ending block and continuing (else, else if)
void init_engine(int a, int b) {
	// ...
	if (a == 20) {
	} else if (b == 50) {
	} else {
		// ...
	}
}

functions

  • keep variable declarations at the top of block
    • if needed, initialize them
void block() {
	int a = 20;
	bool something = false;
	// ...
}
  • keep return type and name on the same line
void init_engine(int* a, const char* b) {
	// ...
}
  • if there are too many arguments, wrap like this:
void init_engine(
	int* a,
	const char* b
) {
	// ...
}

variables

  • * is next to type name, not variable name
int* int_ptr;

static

  • things not used outside of the translation unit should be static
    • applies to functions and global variables

indentation

  • always use tabs
    • set width to your liking in your editor
  • use spaces for alignment
  • things should line up regardless of tab width
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment