Some notes on keeping your code clean and readable.
On naming conventions
There are many naming convention decisions, some important, some not. Here's a quick run down on my takes of them:
Word spacing
There are three major major word spacing conventions (for multi-word identifiers):
- using_underscores
- UpperCamelCase
- lowerCamelCase
This is a fairly arbitrary choice to make — I prefer to be consistent with whatever I'm working with, or the standard library of the language if failing that (I'm starting a new project). For C++, this means I prefer to use_underscores, except with template paramaters, which use UpperCammelCase
Scope warts
These are typically prefixes which indicate what scope a variable is in — g for globals and m for class members is common. I don't use them, and believe you have major problems in need of addressing if the scope is both important and non-obvious in a given situation, that should be addressed instead of covered up with a poor band-aid.
Type warts (Systems Hungarian)
These are typically prefixes which state the specific type of a variable — common examples are i for Int(egers), sz for a Zero terminated String, and so forth. These are basically comments which just repeat the declaration, and have an annoying tendency to be wrong — they're brittle. A waste of screen estate which add no information on how the variable is going to be used. A common example of this is wParam from windows programming — w for a Word, or 2 bytes — which once held true, but wParam has since been upgraded to being a double word, 4 byte type.
Usage warts (Applications Hungarian)
These are typically prefixes which indicate how a variable is to be used or what it's purpose is. Some examples might be rw for Row, p for Pixels, in for Inches, or d for Delta/Difference. I prefer to spell the whole thing out of it's actually necessary in a given scope.
Wordiness
On one end of the scale, you could name your variables the undescriptive a, b, and c. I may kill you in your sleep for such a crime, but you could do it. On the other hand, you could make paragraphs out of their names. That isn't helpful either, everything useful gets buried in the middle. The trick, then, is to strike a balance. Here's some of my guidelines on that:
- No abbreviations, except when it's really bloody obvious for the entire scope (this usually means *one* index looping variable).
- Make sure you state what the variable represents.
- Avoid repeating what's obvious from the scope.
On whitespacing
Whitespacing is a great tool for grouping code to help identify patterns and code groups.
I use tabs for block-indenting (control flow blocks such as if, while, etc):
if ( foo ) {
bar();
baz();
bad();
//<---- tabs
}
…and spaces for alignment indenting:
Fnord( Foo
, Bar
, Baz
);
//^^^ spaces
…as well as inter-line grouping on complex statements:
if ( (foo(a,b,42,c)==baz(23)) && ((fnord_delta<42)||(pie=3)) ) ...;
And newlines for non-control-flow blocks:
//Blah blah blah
//Blah blah blah blah blah
fnord f;
f.frobble();
int ft = f.fourtytwo();
gobble g;
g.call(ft, f);
g.pineapple();
f.gabberwalky();