#ifndef NAME_H #define NAME_H ... //contents of Name.h #endif
The goal of this standardization is to create a uniform structure to the ZynAddSubFX codebase. Although these are the existing standards, it is not to say that they cannot change. For now this document will layout the expectations for the code.
Note
|
This is a draft |
Each layer will be 4 spaces further indented than the previous. There should be no tabs used in the C++ source files.
All source code files should either have the .cpp or the .h file extension. They should all be named after the primary contained class.
The contents of the files should follow the following guidelines for their structure.
With every header file, there should be include guards.
#ifndef NAME_H #define NAME_H ... //contents of Name.h #endif
Standard Practice
Within each file there should be a introductory comment before the include statements.
/* ZynAddSubFX - a software synthesizer File Name - Purpose of File Copyright (C) Dates Developer Copyright (C) Dates Developer Author: Developer name This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License (version 2 or later) for more details. You should have received a copy of the GNU General Public License (version 2) along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ Include files /**the class*/ class bla { }; //empty newline
This allows for a person to quickly see the use of a set file and the primary authors.
Unless there is a good reason to do otherwise, the include files should be in the order of:
Corresponding header file (for .cpp files)
Project headers
3rd party headers
standard libraries
system libraries
This allows for someone to clearly see which headers are included in a complex file.
All upper case abbreviations are not recommended. Unless specified otherwise, camel case is preferred in names.
Classes should always start with a capital letter.
Any given typename should have an _t following the name to show that it is a typename.
For the various items, they should be all upper case with underscores to separate words.
#define NAME #define gt5(x) (x > 5 : true ? false) enum { REC_UNPREPARED = -1, REC_PREPARED = 0, REC_ON = 1 };
Doxygen is used to create documentation within header files. This should be used to tell what each element of the code does. This includes classes, methods, and instance variables.
/**The non bar class*/ class foo { public: /** * The function to preform bar * @param x the number of bars * @return success=0 failure=-1 */ int bar(long x) const; private: long long cache;/**<the data cache for bar*/ }
When properly used the Doxygen comments should allow for easy extraction of class documentation.
There are two acceptable styles for brace placement: * Unix Placement (with one space before brace)
if (condition) { statements; } else { statements; }
Under keywords
class Foo { information; }
Note
|
for one line statements with if, for, while or other control constructs, no braces is preferred with the statement on the next line. |
if(a()) return; while(condition) c();
These two styles with the allowance of no braced statement allows for the programmer to have flexibility while maintaining an overall consistent style.
if (condition) { //optional comment statements; } else if (condition) { //optional comment statements; } else { //optional comment }
The alternative brace style is also acceptable. The optional comments should be used when the condition or the resulting action due to the condition are not immediately clear.
This creates a uniform format for the if statements and allows for comments when appropriate.
Switch statements should be in the following format:
switch(var){ case 1: funcA(); break; case 2: case 3: funcBC(); break; default: funcOther(); break; }
Regular formatting
For a first note, gotos should be used sparingly as overuse may indicate poor code structure.
When they are used, the goto should be left inline with the code. The label should be placed on its own line with no indentation.
while (condition) { statements; if (condition) { goto abort; } } abort: statements;
This allows for the goto’s label to be clearly seen and it does not force the goto to break the flow of reading the main code section.
For brief two state conditions that conditional operator should be used. There should be spacing around the ? and the :. Parenthesis should be placed around the operator in any case where it helps clarity.
func() { return cond ? true_case : false_case } some_long_func() { return some_very_long_expression ? true_c : false_c; }
The added whitespace allows for one to distinguish the cases more easily
There should be a number of places where whitespace should exist and where it should be removed.
Assignment operators should have spacing on both sides
Incrementing/Decrementing should not be detached from the variable it acts upon
Mathematic operators should have spacing on both sides
There should be no whitespace after a *
There should be whitespace after a ,
There should not be whitespace before or in []
There should be whitespace after ; in for loops
char *a = new char[5]; for(int b = 2; b < 4; ++b) a[b] = 0; foo(a, 5);
When defining parameters use one variable per line
char **a = NULL; /**<doc string1*/ char *b = new char[20]; /**<doc string2*/
This allows for clear documentation in many locations. This also for clear initialization that is not cluttered into a limited area.
Declarations should have vertical alignment.
Object a; string b; OscilGen osc; char *d; a = Dog(); b = "teststring"; osc = OscilGen(5); d = NULL;
improved readability
One should not use any trailing whitespace, as it only adds noise to diff utilities.
Within constructs like if statements, it is acceptable to use non boolean terms as the condition.
char *func(char *a, unsigned int n){ if(!a){ return new char[n]; } else if(a){ return a; } else{ cout << "you sure have an interesting compiler" << endl; } }
This eliminates the redundancy needed with extra statements.
For each level of code there should be an indentation of 4 spaces. There should be no tabs used for indentation.
This should be used so that the code will have a uniform look independent of the editor being used.
Lines should not exceed 80 characters.
Note
|
For information on how to wrap overly long lines see section TODO |
Any line over 80 characters will need to wrap on a default terminal.
Should there be spaced after mathematical operators?