Code style guide

Version 0.6, last updated on November 23, 2004.

Copyright © 2004, Philip 'Leffe :(' Nilsson, All rights reserved.

Permission is hereby granted, free of charge, to any person obtaining a copy of this documentation (the "Documentation"), to deal in the Documentation without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Documentation, and to permit persons to whom the Documentation is furnished to do so.

THIS DOCUMENTATION IS PROVIDED "AS IS", IT WILL MOST LIKELY BLOW UP YOUR COMPUTER BUT I TAKE NO RESPONSIBILITY WHAT SO EVER!

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119.

Coding style

General guideline: keep it consistent and readable.

A summary

Header files

Headers must use the K&R style for brackets, K&R puts the opening brackets of functions and other top level structures on the next line like in this example. Structures within the code has it's brace after the structure.

class SomeClass
{
public:
	void SomeFunction()
	{
		if (1) {
			return;
		}
	}
}
			

All header files must use header guards, the header guards should follow the style of this example.

#ifndef SOMECLASS_H
#define SOMECLASS_H
...
#endif//SOMECLASS_H
			

Headers should not contain any code except for minimal inlined functions, although the best choice would be to put that in the source file.

Prototypes in headers must have the same parameter names as in the source files. This is possibly because of the documentation engine.

Source files

In source files, you must use the K&R style.

All files

All files must start with a copyright message and a copy of the license. The license should use '//' style comments. This might be handled by inserting a common header through some script.

All comments should use '//' style comments. '/**/' style comments are to be used in debugging.

Filenames must only use lowercase letters.

Spacing and indenting

All code must be properly indented, it is assumed that the reader knows what that means. Indents must use tabs with a tabwidth of 4 spaces, but any value will do as long as linebreaks are indented properly.

The private, protected and public keywords in classes should not be indented, they should start at the same column as the class does.

	class ClassName
	{
	private:
		/*...*/
	public:
		/*...*/
	protected:
		/*...*/
	}
			

All code must use UNIX newlines, that is, just a '\n'. Anything else will complicate things, and most likely get lost if a source control system is used.

Long lines should be broken at about 80 characters length, indent using tabs to the same place as the line before and then spaces for fine control to a proper place... like this example:

	if (i == 3 &&
	    j == 5 ||
	    k == 7)
	{
		/*...*/
	}
	else
	{
		/*...*/
	}
			
As you can see in the example the code starts again right after the opening parenthesis.

Names

Variables must use camelCase, where the first character in all words is capitalized except for in the first word. Variables should use descriptive names, unless when not needed, counters in loops for example. Macros must use capitals for the entire name, they should not use underscores. All other names must use PascalCase where the first character of every word is capitalized.

Names must only use a-zA-Z characters with the exception of underscore. Numbers are allowed where it is obvious what the number means, avoid numbers if possible.

Member variables must be postfixed with an underscore ('_') to tell them from parameters and local variables.

Namespaces

All code must be contained within a namespace. This will avoid naming conflicts. Both between project code and system code and also different project modules if it is decided that different modules will use different namespaces, with a common base namespace of course.

Include files

Includes must be in the top of the file below the license and above the start of the namespace. System headers should come before the project headers and be separated by a space, all the includes should also be separated by a space from both the license and the start of the namespace.

The include set should not be optimized, include all files needed and do not rely on include files including other files.

Code documentation

General guideline: Keep it documented!

Natural Docs will be used for the code documentation. Natural Docs uses Perl and is thus cross-platform. The syntax used for documentation is clean and simple (as opposed to the the syntax of Doxygen...) but can take up quite a lot of space. The syntax is not only simple by default, but also quite flexible and many different styles of documentation can be used.

A must read is the user manual.

All classes, functions, public/protected member variables, structures, globals, macros, #defines and enumerations must be documented. Arguments to functions must be documented where it is not obvious what an argument is for... might be best to always document arguments.

Commenting of non-public pieces of code, private member variables, complex algorithms, exceptions, etc. should not use NaturalDocs syntax, this is because the person looking for that will most likely already be reading the source files. Things that might look strange to someone from the outside should be documented, the documentation style is up to the programmer, but in most cases a simple one-liner should be enough.

As commenting in ND takes up quite a lot of space, the comment style to be used is as minimal as possible while keeping readability.

// Class: ClassName
//  A class that has a name, inherits from <SomeClass>.
//
//  Classes use Class.
class ClassName : public SomeClass
{
public:
	// Constructor: ClassName
	//  Constructors use Constructor.
	ClassName();
	// Destructor: ~ClassName
	//  Destructors use Destructor.
	~ClassName();
	// Function: DoSomething
	//  Functions must document return values and parameters.
	//
	//  A long description would be nice.
	//
	// Returns:
	//  Describe the return value.
	//
	// Parameters:
	//  abc - What could this be?
	int DoSomething(int abc);
	// Uint: uint
	//  Using the correct types is a good idea.
	//
	//  If none is suitable, just use Variable then.
	unsigned int uint;
private:
	// these are not commented this time...
	int doSomething;
	void DoSomethingElse();
}

// Macro: DOSTUFF
//  Macros should be documented too.
//
// Returns:
//  Macros can be tricky :)
//
// Parameters:
//  x - This works!
#define DOSTUFF(x) (x-x*x+x)

// Define: WIN32
//  Describe #defines too, they can be hard to keep track of.
#define WIN32 1

// Function: main
//  Normal functions are described as class functions are.
//
// Returns:
//  Error!
//
// Parameters:
//  argc - number
//  argv - pointers
int main(int argc, char ** argv)
{
	return 1;
}
		
Follow these examples and read the manual and everything should work really nicely. Crossreferencing is nice, make use of the <> links, to link to something in a class, use ClassName::ClassFunction.

This is a summary of what you have to document:

In the style, the topics are indented by a space, the data in the topics is indented by two spaces. Remember that you need a blank line after the data, and that blank lines in the data starts a new paragraph.

For each documentation item (summary, parameters, ...), this is what you should write:

Summary

The summary should describe the item documented. What it does, why it exists, anything important to know, etc. The first line must contain a brief description. A longer description is only needed if the item documented requires it. Variables will usually not need it, functions will usually need it. This is a template:

// <type>: <name>
//  <insert summary here>
//
//  <optionally insert longer description here>
//
		

Return value

Not much documentation is needed, just what is returned. Any special return values must be documented. This is a template:

//
// Returns:
//  <what does it return>
//
		
If a function returns special error codes or anything like that, make a list in the next paragraph using the NaturalDocs syntax for lists.

Parameters

For each parameter, describe what it is, if it will affect the function in any major way and if it will change. This is a template:

//
// Parameters:
//  <name1> - <description>
//  <namen> - <description>
//