Posted on May 1, 2008 by Doolwind

Doolwind's Game Coding Standard

For some time now I’ve been asked by a few people to write up my thoughts on a coding standard. To me, coding standards are like source control, until you use them you don’t realise just how awesome they are. Coding standards are a requirement for large software teams, however even if you are working alone I’d recommend adopting at least a simple coding standard.Keeping code consistent and readable is helpful when reading other people’s code as well as when reading your own code weeks or months are it was written. In effect a coding standard is trading development time for maintainability time. I’ve found that the ratio of dev time to maintenance time grows from 1:1 on a small project to something approaching 1:∞ on larger projects.

I’d like to formally thank Greg for showing me the light on a lot of these points. I’ve spoken previously about pair programming and just generally mixing the experience level of developers to help the younger ones. I think that these kinds of relationships are invaluable for making great programmer as it’s something that you just can’t pick up from textbooks or coding by yourself.

As always, please add your thoughts and complaints. I think that just talking about these issues is a good step in growing as a software developer, even if everyone doesn’t always agree.

General Tips

1. Be consistent

This is the golden rule with coding standards in any language. Every other rule below is pointless unless there is consistency. If you completely disagree with all of my points below that’s fine, so long as you set out a standard, and everyone conforms to it. The only thing worse than a bad coding standard is not having one or having one that isn’t followed by everyone.

This can be an issue for some programmers as their ego’s get in the way however it’s vitally important that everyone follows the standard otherwise it will quickly turn into bedlam. This consistency should ideally cross both the programmer boundary and the project boundary. It will be much harder to have consistency between projects, however if this can be achieved, any programmer within the company can switch projects freely (even if only to assist briefly). This also increases efficiency on new projects when programmers who haven’t worked together already have this coding standard in common.

2. Get everyone involved

To get the best “buy-in” and to reduce friction amongst the team, it’s important to get everyone involved in the discussions. I’d recommend writing up the standard once “complete” and passing it around as the first draft. Giving people plenty of time to comment also gives leaders more ammunition when enforcing the standard. If people can voice their thoughts on the subject they are more likely to follow the standard in the future.

There is always going to be the inevitable ideological disputes where programmers won’t be able to come to a conclusion. There are really two options here:

i. Military style: The highest ranked programmer makes a decision, and everyone follows suit. This may be the only way to solve the most ideological debates but has the side effect of lowering morale.

ii. Politician style: Both sides put their case forward and the entire team (or key members) vote on which to choose.

Specific Tips

3. Curly braces – on the next line

if (condition)
{
}

This is pretty much the standard I’m seeing everyone use these days. There are some strange lecturers and Java programmers that keep the brace on the same line, but otherwise most people seem to have unofficially agreed to this. This has the added advantage of allowing the condition to be commented out quickly (using //)

Negative: It takes up less space having it on the same line.
Response: It makes code far more readable, and white space is free and should be used.

4. Always put curly braces in

The main reason for this is that it reduces errors in code such as a macro hiding the fact its multiple statements. The secondary reason is for maintainability. If the single statement becomes multiple statements it takes longer to update, and can lead to errors if people miss adding the braces.

Negative: It saves time to leave braces out.
Response: Saving time at the expense of readability is bad. If all conditions/loops have braces then the source will be far more consistent.

Negative: It takes up less space without braces and more code can fit on the screen.
Response: Fitting more code on screen is not as important as having error free, maintainable code. As desktop resolutions increase this argument holds even less weight.

5. Prefix members and arguments

class MyClass
{
int m_myInt;
};

void MyFunction( int a_myParam )
{
}

Firstly, adding these prefixes is NOT Hungarian notation. Rather than describing the type of a variable adding these prefixes gives context about what the variable is. This context is the key reason for adding prefixes. Prefixes make it easier to build a map in your mind of what the code is doing as you can quickly tell what variables are arguments/parameters, which are members and which are simply local variables. You can also add g_ to globals, however I’d be advocating the use of globals then J.

If m_ and a_ are too verbose then the alternative is simply appending m and a.

void MyFunction( int aMyParam )
{
}

Personally, I prefer the full prefix (m_) as it makes the code more readable, and it follows the convention of the first character of the variable name being lower case.

Negative: With modern IDE’s you can mouse over variables to get extra information
Response: Mousing over is slower than simply perusing code. The information given is usually just the type which doesn’t give context, it only gives further information.

Negative: It takes too long
Response: Again, readability is more important than saving a few seconds on typing

Negative: Underscore is hard to type
Response: Once you’ve been using it for a while it becomes quite natural. Also with tools like visual assist the underscore can automatically be added in for you.

6. Put modifiers (* and &) next to variable type rather than variable name

MyClass* myVariable;

This point actually goes against what I am seeing most people using in their coding standards at the moment. It also goes against what I was taught at university (whether that’s bad or not I don’t know). Before you dismiss it though, I recommend you actually sit and think about the alternatives and why you would use them. The modifier (pointers or reference) is modifying the type of the variable and therefore it should be placed next to the type itself. The negative to this is one I gave when first taught this, however after thinking about it I realised the error of my ways.

Negative: The modifier should go next to the variable name as it is misleading if you declare multiple variables per line. In the example below, the first variable is a pointer and the second is not, this is misleading.

MyClass* myPointerVariable, myNonPointerVariable;

Response: Declaring multiple variables on one line is really the exception to the rule. Should you be making a decision about based on the exception or the rule? If there are any modifiers like this, don’t declare them on the same line. The worst issue here is a bit of extra typing and more screen real-estate being used up, neither of which should be an issue. Having the pointer next to the variable name makes it harder to reader when skimming over code, particularly if there are a number of spaces (or tabs) between the type and name.

7. Create const on functions and function arguments where appropriate

Const correctness for variables is a bit like cleaning your teeth. It’s annoying to do, but everyone agrees that you should do it. There are three main benefits:

i. More descriptive code. A quick look at a function tells you whether it changes the state of an object, and whether it changes the state of any variables passed in.

ii. Faster code. Giving the compiler more information about constness allows it to optimize your code.

iii. Less errors. If a function or argument is const then anyone changing the function will get compile time errors if they do something the function was never intended to do.

8. Conditions/Loops should have a space after them

if (myVar)
{
}

This is the most readable way of writing conditional and loop statements I’ve seen. I personally recommend this usage, however the main reason for this point is to get you thinking about how it should be done. If you disagree, that’s fine, just make sure you remember point #1 and decide how you want your code to look and keep it consistent.

9. Camel case variables, capitalize classes and functions and full capitalize constants

I’ll finish up with an easy one. Most people agree with this standard but I thought I’d list it anyone. The best way to show this is with examples:

Variable:

int myVariableName; // camel case

Class and functions:

class MyClassName {} ; // camel case with capital first
void MyFunctionName();

Constants:

const int MY_CONSTANT_NAME = 5;