E-Cell 4 Coding Guide rev. 3
| Authors: | Koichi Takahashi |
|---|---|
| Date: | May 11th, 2009 |
Introduction
This document describes the coding standard for the E-Cell System Version 4 development and related projects.
To keep it compact and handy, this document primarily intends to disambiguate things that are useful in giving standardized appearance to program codes, such as naming conventions and file layout. Many tips that are supposed to be obvious to intermediate to advanced programmers are not included (such as that C-style casts should be avoided as much as possible in C++). E-Cell project coders are referred to more comprehensive documents such as Effective C++ and More Effective C++ for C++, and Python Enhancement Proposal 8, or PEP 8, PEP 20, PEP 257 and PEP 287 for Python coding.
Common
Indentation / Punctuation
Keep lines to 79 characters or less.
Indent with 4 spaces.
Do not use tabs for indentation. Use exclusively spaces.
Do not put whitespace immediately inside parentheses, brackets or braces.
Do not put whitespace immediately before comma, semicolon or colon.
Do not put whitespace immediately before the open parenthesis that starts the argument list of a function call, indexing or slicing.
Put a space after a , or :, when it is not the last character in the line:
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--)
Do not use more than one space around an assignment (or other) operator to align it with another:
x = 1 length = 2
not:
x = 1 length = 2
NOTE: above rules are consistent with Python Enhancement Proposal (PEP) 8.
Names
General
Do not abbreviate
(There are exceptions. See below).
Constants and variables
Constants
Use capital letters, words separated with underscores:
SOME_CONSTANT
Variables and function/method parameters
Use the underscore ('_') to separate words. Basically use lower case.:
length max_length
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, m, n in this order.
Classnames
Upper camel case must be used for names of all exposed classes constituting programming interface of the package:
ClassName
Exception classes
Names ending with Exception, Error and such are recommended:
NonFatalException
Functions and methods
Use the underscore ('_') to separate words. Basically use lower case:
function_name() method_name()
Prefer verb+noun form for functions and method names.
Factory methods
create + classname or nature of the object to be created:
create_Proxy()
Converter methods
to + classname or nature of the target:
to_Real()
Getters and setters
get or set + the name of the attribute:
get_length() set_length()
Boolean predicates
is + adj., can + verb, has + past particle, verb, or verb + noun with the object as an implicit subject:
this->is_empty() this->can_stop() self.has_attribute() self.contains() self.contains_key()
Style
- Put one statement per line.
- Initialize all members in constructors.
Python
Style
- Do not use module variables as variables. Use only as constants.
- 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 numpy
MODULE_CONSTANT = 0
def some_module_function(a, b):
'''Docstring.'''
return a + b
class SomeClass:
'''
SomeClass docstring.
'''
CLASS_CONSTANT = 1
class_variable = 'foo'
def __init__(self):
'''
Constructor docstring.
'''
self.object_name = ''
self.key = ''
self.length = 0
def set_length(self, length=0):
'''
Docstring for set_length.
'''
self.length = length
def update_key(self, key):
'''
Docstring for update_key.
'''
self.key = key
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();
Namespaces
Do not indent the contents of top-level namespaces:
namespace ecell { class Foo { ... }; }not:
namespace ecell { class Foo { ... }; }Do not omit brackets around a one-line block:
if (a < b) { return; }not:
if (a < b) return;Do-while
while must be on the same line as the closing brace.
do { ++x; } while (x != y);
Names
Put an underscore '_' after private member variables:
class Foo { private: int length_; Position& center_position_; };
Style
Do not use #define for constants. Use const variables.
const Int MAX_SIZE(100);
not
#define MAX_SIZE 100;
Use assert only to capture bugs. Otherwise use exceptions.
e.g. Don't use assert to check validity of user input.
Comments
- All public classes and methods must be commented.
- Make comments in Doxygen-Javadoc style.
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 stuff public: // repeat this even if there is another public: above. Foo(); // constructor ~Foo(); // destructor // setter / getter methods void set_length(const int&); const int get_length() const; // other public methods void clear(); void initialize(); ... // operators protected: // protected methods private: // private methods protected: // protected member variables. private: // private member variables. int length_; Position& center_position_; };
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:
(add-hook 'c-mode-hook
'(lambda ()
(c-set-style "bsd")
(setq c-basic-offset 4)
(setq indent-tabs-mode nil)))
(add-hook 'c++-mode-hook
'(lambda ()
(c-set-style "bsd")
(setq c-basic-offset 4)
(c-set-offset 'innamespace 0)
(setq indent-tabs-mode nil)))
(add-hook 'python-mode-hook
'(lambda()
(setq indent-tabs-mode nil)))
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 --unpad=paren --pad=oper --convert-tabs
