[Home]  [Prev]  [Next]    A guide, a tutorial for developing well-designed cross-platform applications

B. Coding standards

Ideally any code should be readable like a science fiction book. This means code should be outlined rather similar as text. After all code is just some kind of structured text, the only difference is code is more formal than ordinary text.

Guidelines for coding standards are rather difficult to formulate and are mostly subject to the personal taste. But coding standard is a very essential requirement to make code readable and understandable. Understandable not only by you but by all the others who wants or have to read through your code. I doesn't matter much which taste is chosen it only matters that the chosen taste is easily understandable by anyone.

Just assume once that someone uses your application and stumbles across a bug. Now if he were able to look through your code, understands it and sends you a patch or at least provide enough hints, how much easier would it be for you? Isn't it then a good idea to make your code as readable as possible by others? But that's only possible if both sides use the same (or similar) coding standards.

The coding standards are well in line with the "Linux kernel coding style" or the "Busybox Style Guide" (see References).

B.1 Naming

Rules for choosing good names are rather difficult to specify. But naming is nonetheless not an obscure art as some may think, it's just difficult since names always have a context around them which influences their naming. Names are best if the simply are the most specific synonym of their content and are most apart of the names nearby.

The usual rule about size of a name should not be followed too strictly. It's much better to make important (global) names longer, less important (local) names shorter. So it's perfectly correct to use "i" for a loop variable while it's completely nonsense to call an important function "i". Don't call a loop variable "loopIndexOfFunctionXY" when this long name doesn't provide additional needed information, while it makes sense to call it "pos" if it refers to a position.

Don't use acronyms unless they are well establish and are usually know by the vast majority of developers. If you want to shorten a long name better consider copying it into a local variable. It almost never makes sense to shorten function names.

A name should usually just mean what it does or what it stands for. So a name of a function should specify what a function does, even if this means a longer name. So function names are usually action descriptions while variable names are usually object descriptions.

In class oriented languages (C++) it's a good idea to make the scope of an object visible. Global objects should have a "g_" prepended, class objects (members) a "m_" while local object may not have a prefix. Other languages might distinct between global ("g_") and local (no prefix) objects. If you make the scope visible you have to be consistent and do it throughout the full project. Contrary to objects it's not necessary to improve the readability to prepend functions (actions) since their scope is most of the time easily spotted.

A locale name should never be the same as a global name, overriding the global definition. Always make a name distinct, otherwise it leads to confusions and miss understandings. The above mentioned visible scope will help to prevent it.

It's not a good idea to prepend (nor append) the type of an object to its name. There aren't enough symbols to be consequent and they conflict with the scope, making it useless. Appending a type makes only sense if it's needed to distinguish between the equally named variable and the type.

In some languages where working with pointers is important pointer variables are prepended by "p_" or "p". In object oriented languages (like C++) any actions is done on the object regardless how many indirections are involved. Do whatever you like.

If you can avoid it don't use letter case to distinguish between objects. Do it only between objects and their types and even then avoid it. Use case to make names better readable but always use identical writing even not enforced by the language or compiler. If you prefer use underscores to improve readability.

B.2 Conditional compilation

Conditional compilation is an easy way to make your code small while still has a lot of features. But conditional compilation makes your code a lot more difficult to read and today's compiler are able to remove unneeded code by themselves. So it's not necessary anymore to use conditional compilation.

The only case to use conditional compilation is when different APIs enforces its use. This is most probably only the case for missing or different cross-platform features. To avoid this it might be considered if differences could be moved into the used framework. If this isn't possible consider moving conditional code into subroutines to keep the main code clean and readable.

Since more and more decisions are required during runtime than compile time, it's better to avoid conditional compilation altogether and try to implement a plug in structure. While this means a lot more effort at the beginning your code will greatly win in the end.

B.3 Statements

A statement usually should fit on a single visible line (if possible). If not, it has to be divided on an obvious point, after an operator or after a separator (i.e. ","). This means the operator or separator should be on the end of the line and not at the beginning of the next line. A multi line statement should be indented to the functional same point as the start line.

Multiple statements shouldn't be put on the same line unless they belong together as if they were a single statement.

B.4 White space

White space or no white space is very important possibility to make code readable. But white space is only useful if used sparingly. Don't put white space (or near white space, see braces) between something which belongs together but where a divider line is needed. With divider lines your code looks like any ordinary text put in paragraphs.

Tabular coding, indenting elements so the fit well with similar elements on nearby lines, is another way to improve readability. But it makes only sense if the indent is always updated when the need arises. This constantly updating of lines without code changes aren't liked in some projects. Use it sparingly.

B.5 Braces

Braces in code should be handled as in text. That means at least one single space has to be before an opening brace and no white space should follow. Vice versa no white space before a closing brace followed by at least one single space. But this isn't as important for readability, therefore other kind of white space uses is okay as well.

Remark about "else": Instead of writing braces around "else" on separate lines (totaling 3 lines), it should be written "}else{" (just on line). The lines with just one brace look rather similar as just white space and imply a divider line where none is. So better use always "}else{" even if a true divider line is needed. If you more like to use "} else {" just go ahead.

B.6 Blocks

A block statement (i.e. "if", "switch", function.) should always have braces ("{", "}") unless the block fits on a single line. In other words a block statement without braces should never be split on several lines (see B.2).

The opening braces of a block statement should always be on the end of the starting line, not on the beginning of the next (see B.3).

B.7 Comments

Comments are good but readable code is better. Always when you have to describe how your code works, consider to make your code clearer. As far as possible, comments should always describe the code's effect as a whole and/or why it is doing this and not describing the code as it is. Any comment should give some additional information.

A comment acts usually as a title for the next few code line and should be prefixed with a divider line (white space). A code segment looks like a paragraph where the first line(s) are comment(s).

Comments are also welcomed as a class description in the class declaration. This is usually a multi line comment associated with the class but not followed immediate by code lines.