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

  1. Install astyle.
  2. Install Plugins
    • CDT
    • Pydev
    • Astyleclipse (optional)
    • Subclipse (optional)
  3. Window->Preferences->C/C++->Editor->Appearance->Insert space for tabs
  4. Astyle configuration.
    • Window->Preferences->C/C++->Code Formatter: Astylipse.
    • Window->Preferences->Astyle->style = ansi
    • Window->Preferences->Astyle->Other options as below or use ~/.astylerc.
  5. 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