E-Cell 4 Coding Guide
| Authors: | Koichi Takahashi |
|---|---|
| Date: | 6/16/2008 |
Introduction
This document describes the coding standard for the E-Cell 4 project.
To keep it compact and handy, this document primarily intends to disambiguate things that (1) may have multiple correct approaches and (2) can affect appearance of programming interface and implementation (such as indentation styles and naming conventions). Many tips that are supposed to be obvious to intermediate to advanced programmers are not included (such as that casting should be avoided as much as possible in C++).
Common
Indentation / Punctuation
Keep lines to 80 characters or less.
Indent with 4 spaces.
Do not use tabs for indentation. Use exclusively spaces.
Put a space after a right brace ('(','[','{'...) and punctuation (',',':'...).
Put a space before a left brace (')',']','}'...):
f( a, b, c ) [ 123: 456 ], { "abc": "def", "ghi": "jkl" }Insert spaces around binary operators, but not around unary operators:
( ( a + b ) * c ) * *d--
not:
((a+b)*c)*(*d--)
Names
General
Do not abbreviate
(There are exceptions. See below).
Constants and variables
Constants
Use capital letters, words separated with underbars:
SOME_CONSTANT
Variables and function/method parameters
Start with a lower letter, capitalize the first character from the second word:
variable someVariable
Prefer one-word names for function/method parameters:
function( name, id )
Loop counters and iterators
Local counters and iterators primarily used in a single loop may be one character alphabet; such as i, j, k, l in this order.
Boolean variables
is + adj., can + verb, has past particle, verb, or verb + noun with the object as an implicit subject. (See also Boolean predicates below.)
Classnames
Start with a capital letter. Capitalize the first character from the second word:
ClassName
Exception classes
End with Exception:
NonFatalException
Functions and methods
Start with a lower letter, capitalize the first character from the second word:
functionName() methodName()
Prefer verb+noun form for functions and method names.
Factory methods
create + classname or nature of the object to be created:
createProxy()
Converter methods
to + classname or nature of the target:
toInteger()
Getters and setters
get or set + the name of the attribute:
getLength() setLength()
Boolean predicates
is + adj., can + verb, has + past particle, verb, or verb + noun with the object as an implicit subject:
this->isEmpty() this->canStop() self.hasFinished() self.contains() self.containsKey()
Style
- Put one statement per line.
- Initialize all members in constructors.
Python
Style
Do not use module variables as variables. Use only as constants.
Properties vs. setter/getter methods
Prefer properties to setter/getter methods when accessing members.
Comments
- All functions, classes and methods that constitute programming interface of the module must be commented properly.
- Use docstrings in reStructured Text format to document classes, functions etc.
Others
- Use of pychecker is recommended.
Example
import SomeOtherModule
MODULE_CONSTANT = 0
'''
Docstring.
'''
def someFreeFunction( a, b ):
return a + b
'''
SomeClass docstring.
'''
class SomeClass:
CLASS_CONSTANT = 1
classVariable = 'foo'
'''
Constructor docstring.
'''
def __init__( self ):
self.objectName = ''
self.key = ''
self.length = 0
'''
Docstring for setLength.
'''
def setLength( self, length = 0 ):
self.length = length
'''
Docstring for updateKey.
'''
def updateKey( self ):
newKey = self.getNewKey()
self.key = newKey
C++
Files
Names of C++ source files must end with .hpp or .cpp.
A public class must be contained in its own header file.
Private and auxiliary classes may be contained in header files of other public classes.
Indentation / Punctuation
Indent in BSD/Allman style.
if ( a > 0 ) { something(); }not:
if ( a > 0 ) { something(); }nor:
if ( a > 0 ) { something(); }nor:
if ( a > 0 ) something();
Do-while
while must be on the same line as the closing brace.
do { ++x; } while ( x != y );
Layout
Basic layout of a header file:
#ifndef __FILENAME_HPP #define __FILENAME_HPP // #include directives // typedefs // auxiliary functions // private / auxiliary class declarations // main class declaration #endif /* __FILENAME_HPP */
Basic layout of a class declaration:
class Foo : public FooBase { public: // optional // typedefs and other type-related things public: // repeat this even if there is another public: above. Foo(); // constructor ~Foo(); // destructor // setter / getter methods void setXXX(); const TTT getXXX() const; // other public methods void clear(); void initialize(); ... // operators protected: // protected methods private: // private methods protected: // protected member variables. private: // private member variables. };
Style
Do not use #define for constants. Use const variables.
const Int MAX_SIZE( 100 );
not
#define MAX_SIZE 100;
When there is nothing to do in a block, do not leave it empty. Instead, put ; // do nothing.
if ( a != b ) { ; // do nothing } else { something(); }void doNothing() { ; // do nothing }Use NEVER_GET_HERE to indicate portions of code that must not be reached.
if ( ... ) { } else if ( ... ) { } else { NEVER_GET_HERE; }switch ( ... ) { default: NEVER_GET_HERE; }Use assert only to capture bugs. Otherwise use exceptions.
Don't use assert to check validity of user input, for example.
Always use this-> to access member variables.
const Real getTime() const { return this->time; }not
const Real getTime() const { return time; }Signatures of setter / getter methods must be as follows:
void setX( Param<T> value ); const T getX() const;
where T and X are the type and the name of the attribute, and Param<T> is const T when T is a POD type, and const T& otherwise. The parameter name of setter function must be value.
Do not use C-style casts. Use C++-style casts or boost casters (such as lexical_cast<>).
Comments
- All public classes and methods must be commented.
- Make comments in Doxygen-Javadoc style.
Miscellaneous
Packaging
- Comply with the Filesystem Hierarchy Standard.
Documentation
- Use reStructured Text for text documents in the package.
- Use DocBook version 4 for other documents (such as reference manuals and tutorials).
Appendices
Sample editor/formatter settings
Emacs
.emacs file may contain:
;; prohibit tabs. (setq-default indent-tabs-mode nil) ;; C++ (setq c-default-style "bsd") (setq c-basic-offset 4) ;; No special customization for python-mode.
Eclipse
- Install astyle.
- Install Plugins
- CDT
- Pydev
- Astyleclipse (optional)
- Subclipse (optional)
- Window->Preferences->C/C++->Editor->Appearance->Insert space for tabs
- Astyle configuration.
- Window->Preferences->C/C++->Code Formatter: Astylipse.
- Window->Preferences->Astyle->style = ansi
- Window->Preferences->Astyle->Other options as below or use ~/.astylerc.
- Pydev configuration.
- Window->Preferences->Pydev->Tabe length = 4, Substitute spaces for tabs = yes, Use code folding = yes.
- Check Pydev->Code Formatter->Use space after commas and Use space before and after parenthesis.
Artistic style code formatter for C++
The following gives somewhat acceptable results, though not perfect.
astyle --style=ansi --indent-namespaces --pad=paren-in --pad=oper --convert-tabs
