Links
Fawkes Software:
Development:

Advertisement

Table of Contents

Introduction

The purpose of the Fawkes Software coding standard is to help maintain quality of the product by keeping the code base consistently readable. Without some kind of ruleset in place, each contributing developer may submit code formatted using their own personal style, which might not be understandable to others. The worst case would be if a submitted change were not in any way consistent with existing code, making it more difficult for all involved to read the source and therefore reducing efficiency of the development team. By enforcing this coding standard, consistancy, and therefore readability, are improved, meaning an overall increase in efficiency of the development team.

Unfortunately, there are many different coding styles, and few agree on much. How, then, to choose which style to use? The Fawkes Software coding standard tries to help improve readability by minimizing unnecessary characters, while still maintaining spacing to better convey the flow of logic through the system being implemented. Some developers may not agree with the spacing rules, or decisions of which constructs to use given equivilent outcomes, but this is unavoidable given free will.

To increase readability of our source code, we have created this document to explain how all source should be formatted. This document tries to cover all possible source, but specific cases will be covered when they happen. Discussions on the standard, including suggestions for improvement or including special cases, can be carried out at the forum.

Any source that does not follow the standards may be reformatted so that it does, or it may simply be rejected. Which is chosen depends on whether or not a developer steps up to reformat it, and therefor may depend on length, complexity, clarity, and other factors as deemed by the developer. To prevent rejection or wasting time, please format submissions as per this document. Thank you.


C-Style Languages

C-style languages include any language that are formatted similarly to C. This includes C (obviously), C++, Java, PHP, PERL, and others. Of these languages, C, C++ and PHP are the three most commonly used by Fawkes Software. This section describes how to format source for these languages, covering language-specific extensions wherever necessary.

Header Comments

Header comments serve several purposes. They identify which project the source file belongs to, as well as what the project does. They give the copyright information for the source file, and they describe what it is the source file actually does. The format of the header comments is rather simple:

/*
	Project Name - Project description
		[Continuation of project description]

	Copyright (c) YEAR, Owner. Project License
	
	File.name: Description of file
		[Continuation of file description]
*/

Items in the [square brackets] are optional. The license line(s) must at least contain copyright information. If the project license is too long, it may be referenced in a separate file. If an optional item takes more than one line, all of the extra lines should be indented the same amount.

Naming Convention

Type names and class names must be capitalized CamelCase with no underscores. Function names and variable names must be regular camelCase. #defines must be all capital with underscores separating words if needed for clarity. No names may begin with an underscore unless required by an API or external library. "Hungarian notation" is not allowed. Class member variables are to be treated like normal variables when naming.

// A type name
typedef int TypeName;

// A class name
class ClassName;

// A function name
void functionName();

// A variable name
int variableName;

// A define or constant
#define DEFINE_NAME 1

// An invalid name
int _invalidName;

Source Comments

If comments are not part of the header comment block, they are source comments. These comments must precede the line(s) they describe, and must be indented to the same level as the code. The comment sequence must be followed by a single space. The only exception is "commented out" code, where the comment sequence must be at the beginning of the line for single-line comments, or at the beginning of their own lines for block comments.

	// Prints "Hello World!" to the console:
	std:cout << "Hello World!";

//	std:cout << "Commented-out code.";

/*
	std:cout << "This is a block of" << std::endl;
	std:cout << "commented-out code.";
*/

Function Declarations and Definitions

Each function declaration must go on it's own line. Functions not taking parameters must have an empty parameter list in languages where this is allowed. There must not be a space between the function name and it's parameter list. Parameter names must be included in both the declaration and definition, and must be descriptive of their purpose.

// Function that takes no parameters
void function1();

// Function that takes 2 parameters
int function2(bool returnValueUnchanged, int value);

Curly Blocks

Any block surrounded by curly brackets must have the curly brackets each on their own line, with the contents indented. The body of a case or "default" in a switch block must be inside a curly block unless the case is empty. If a single statement is in the body of an if, else, or a loop, then the single statement should be on the following line (barring a comment which should be indented to the same level as the statement) and indented one level. Otherwise, the body should be in a curly block. One situation where you might include the curly braces anyway is if you expect to add more statements to the loop or if's body.

if(true)
{
	statement();
	statement();
}

switch(true)
{
	// Empty case
	case false:
	case true:
	{
		// do stuff
		statement();
		break;
	}
}

if(true)
	// comment
	statement();
else
{
	// multiple statements
	statement();
	statement();
}

Loops and If Statements

Loops and if statements must not have a space between the keyword and the condition for consistency with function declarations. An intentionally empty while() or for() loop body must have a pair of curly brackets both on the same line as the loop definition with a single space between them. The ?: operator may be used as an inline if statement that returns a value.

// single-line loop body
while(str[i])
	++i;

// Single line loop withing a multi-line loop
for(int y = 0; y < height; ++y)
{
	for(int x = 0; x < width; ++x)
		img[x + y * width] = img[x + y * width] / 2;
}

// empty loop
while(true) {}

// ?: example
bool plural = seconds != 1;
std::cout << "There " << (plural? "are " : "is ") << seconds << (plural? " seconds" : " second") << "left";

Operators

There are only three operators that must not have spaces on either side: The scope operator ("::"), the dot operator (".") and the arrow operator ("->"). This helps provide a sense of belonging for members of classes, structures and namespaces.

The unary "*", "&", "++", "--" and "-" operators must have only a single space to one side, depending on where they're used. The "-" must always be attached to the number or variable it's negating. The "++" and "--" operators must be attached to the variable they're modifying, preferably prefixing though it depends on the desired effect. With "*" and "&" if there is no variable then the operator must be attached to the type, otherwise it must be attached to the variable. The only exception is the "pointer to a pointer" case, in which one "*" must be attached to the type, and one "*" must be attached to the variable.

All binary operators must have one space on either side.

// Pointer (unary * with variable)
char *cStr;

// Pointer (unary * without variable)
int* createArray(int size);

// Reference (unary & with variable)
void Foo::saveString(const std::string &str);

// Reference (unary & without variable)
Foo& Foo::operator += (Foo in);

// Negate (unary -)
int x = -2;

// Increment and decrement operators;
int wtf = --i++;

// Any binary operator
size_t foobar = foo + bar;

// Scope operator
std::string title = "Hello";

// dot operator
size_t size = title.size();

// arrow operator
foo->saveString(title);