- Usage
- Settings
- Modules
- Admin
- ???
- Client
- ???
- Admin
- Introspection
- ???
- Receive
- ???
- Route
- ???
- Send
- ???
- Validate
- ???
How code should be formatted can be controversial.
Some code styles are enforced in ways that would empress religious zealots.
While some of the following styles go against the commonly accepted formatting, the reasoning will be explained.
Naming Things
Format
All names (including filenames) will be lower-case with words separated by an 'underscore'.
All typedef
's will have a _t
suffix.
All define
s will use upper-case with words separated by an 'underscore'.
Reason
OK, this one is mostly dogma.
Which parts is not dogma?
- When talking about the code, at no point does the question of "Which letters are capitalized?" ever come up.
- This naming convention is also what the C/C++ standard committee uses. (More of an excuse or justification.)
Tabs and Spaces
Format
Use tabs for indenting and spaces for aligning.
Reason
What is the best amount of spaces to indent? Some say 2, 3, 4, or even 8 spaces for indenting a block of code. No matter which is selected, there will be some people that disagree. The solution is to use tabs, everyone will disagree but everyone can set the tab-width to be their preferred amount of indenting. Yes, by making everyone upset, everyone can have what they think is the best amount of spaces for indenting.
Continuing with the topic of tabs for indenting, software projects that use tabs for indenting do not have the problem of inconsistent indenting. "Inconsistent indenting" is when some code uses 3 spaces and other sections of code use 4 spaces for indenting. A study was conducted in the late 1990's that showed 95% software projects that used spaces for indenting had inconsistent indenting problems. Of the same projects that used spaces for indenting, over half of them also used tools to fix the indenting.
So think about it, most people that insist that spaces must be used for indenting also insist on using tools to enforce (fix) code indenting. This is a clear example of religious zealotry where people can not except that their way (using spaces for indenting) is inefficient at best or does not work at worst.
A personal side note when I (Zakero) lead a team of programmers, I had everyone use tabs for indenting. For 3 months, the team had ZERO problems with inconsistent indenting during code reviews. Then management forced us to go back to using spaces for indenting and the problems returned. The team was surprised to learn about the results of the "Tabs vs Spaces" experiment and wanted to go back to using tabs.
Now on to the topic of "spaces for aligning". Alignment happens after the first word of code. For example, defining a variable typically starts with the data-type followed by the variable name. The data-type is indented. The variable name can be aligned, using spaces, with other variable names. If a line of code needs to be split into 2 or more lines, each split line is only indented. Split lines are not aligned with the previous line, unless by coincidence. Comments that appear at the end of a line of code can be aligned.
Another way to look at it, never have spaces before or after a tab. This way the tab-width of a tab can be changed and the alignment will not break.
All present day editors can change the width of a tab, so arguments that tabs indent the code too much are no longer valid.
In fact, most terminals and web pages can also change the width of a tab.
Block Characters
A block of code is any code that appears between the block identifiers.
In C/C++, the block identifiers would be the {
and }
characters.
Format
The block identifiers will be on a line by themselves and will not be indented. The code inside the block identifiers will be indented.
Reason
Consistency, pure and simple.
Some coding "standards" have different placement of block identifiers for different context.
For example, {
should appear on the line after a function but should appear on the same line as an if()
.
For consistency, every code block will have the {
on a line by itself and the next line will be indented.
The block end }
will have the same indenting as the matching {
and may or may not have code after it.
For example "} while(some_condition);
" or "} break;
" in a switch statement.
Operators Lead Line Splits
Format
When splitting a line of code into multiple lines, the start of the next line will be indented and begin with an operator.
Reason
Sometimes it is not clear where to split a line of code, such as an if()
with many conditions.
Having a "rule" for where to split helps provide some clarity.
Also to expand on the if()
example, having the comparison operators at the start of the line removes the need to scroll to the end of the line to find the comparison operator.
For functions, the comma (,
) that appears between arguments serves as the operator.
When function parameters are split into individual lines, this provides many unexpected benefits.
Typically when modifying code, the first parameter does not change so updating the other parameters does not require changing the format.
(ie: oops, forgot to update the comma)
If using Doxygen for documentation, each parameter can be documented in-line.
For example:
void some_funcy_func(float foo ///< foo is a thing
, int bar ///< bar is also a thing
)
Bind Left
Format
When defining variables, bind attributes to the data-type not to the variable name.
Reason
Simplicity.
In C/C++, a pointer (*
) or reference (&
) is an attribute of the data-type.
When the code is being used, the *
or &
change how the variable name is interpreted by the compiler.
Function prototypes in C/C++ do not require the parameter name but does require data-type attributes. So, following "Bind Left" also provides consistency.
There is a theory of cognitive consistency.
When reading code, if &var
always means "address of var
" then the code can be mentally parsed faster than when compared to sometimes &var
means "address of var
" and sometimes means "var
is a reference".
No studies on this have been done but it has been my (Zakero) personal experience with other programmers.
Example (C/C++)
This is an example of all the styles described above in action.
>
is the tab character.
.
is the space character.
/**
* \brief Get the next Magic Number.
*/
int.make_magic(int.modifier.///< The value of change (comments align by coincidence)
> ,.const.int&.mode...///< How to modify the value
> ,.int*.......secret.///< Save the magic (variable name aligned with spaces)
> )
{
> switch(mode)
> {
> > case.0:.// Add
> > > magic.+=.modifier;
> > > break;
> >
> > case.1:.// Multiply
> > {
> > > magic.*=.modifier;
> > }.break;
> }
>
> // Toggle all the bits if
> if(magic.&.1.==.0........// the LSB is 0
> > ||.modifier.==.0.// or the modifier is 0
> > )
> {
> > magic.^=.0;
> }
> else
> {
> > *secret = magic;
> > magic.=.-1;
> }
>
> return.magic;
}