From Van Essen Lab

Revision as of 00:10, 8 September 2011 by Jschindl (Talk | contribs)
Jump to: navigation, search


Coding Standards

A reasonable coding standard will make code maintenance and development easier.

Most of these recommendations are from the Java Coding Conventions document that is reasonably short and clear.

Be a thoughtful, careful coder

This rule appears first, to help balance out the rules following it. The number one rule should always be to understand the logic behind why you are applying a certain rule, and be aware of when it's a good idea to break a rule.

  • Periodically examine why certain rules exist and be willing to reevaluate them. If a group of programmers (including oneself) emphatically says never to do something, you should probably focus on that rule first.
  • Usually applying rules in a sub-optimal fashion "feels" wrong. Listen to that intuition, and think carefully if a certain rule applies in that case. Constantly evaluate if a certain practice is providing the return in efficiency that you thought it would.
  • If a certain rule is causing you to write lot's of boiler-plate, think carefully about how to reduce it.
  • If you find yourself going on auto-pilot while writing certain sections, think about ways to automate it, to both reduce the amount of boiler plate, and make coding more efficient.

Below are a few examples (that I've seen in real life over the past 11 years of programming) that demonstrate why rigidly following rules is a bad idea:

    • RULE: Use Object Oriented Principles for EVERYTHING.
    • CONSEQUENCE: Code is less efficient, as even simple things may be bound with overhead. Developers may mistakenly ratchet unrelated classes into an inheritance hierarchy (a very common problem), creating a tangled mess of code that is impossible to refactor. Mis-applying inheritance is a much worse problem than using goto, and is a blind spot among many programmers.
    • RULE: All methods pertaining to a class belong inside it
    • CONSEQUENCE: Things like operator overloading flat out don't work if one implements them inside the class. However, if one approaches programming with the idea that functions are always bad, then it may never occur to them that they can easily work around this by putting the method outside the class.
    • RULE: Only allow a class's data to be accessed through a method.
    • CONSEQUENCE: Over half the lines of code end up being boiler plate setter/getter functions. Massive amounts of time can be lost following this rule.
    • RULE: Always put separate classes inside a separate file.
    • CONSEQUENCE: Files give one the opportunity to create another level of logical organization that inform the programmer about where the important stuff is. It also gives one the opportunity to put classes that are closely related in the same place. Missing this opportunity can create a flat organizational structure that is difficult to understand, with a 10 line Enum class taking the same conceptual space as a class that manages everything.
    Further, spreading code out across many files can create programming sessions that involve tabbing through several dozen files to get anything done. Having to constantly open and close a few dozen files to get something done is very time consuming and slow.

There are many other rules that, if applied properly, produce great results, but when applied in a one-size-fits-all manner, can be disastrous.

Use an IDE!!!!

Be lazy (productive), use an IDE that will provide code completion, automatic indentation, etc. Make sure the IDE is setup to insert spaces and NOT tabs.


Use CamelCase naming as in the Java API. Caret has used this commonly implemented system since it was created. With CamelCase, each identifier is a series of words joined together without underscores or hyphens. In some cases, the first letter is capitalized. In all case, the first letter of the second and additional words is capitalized.

  • With the exception of classes, identifiers (members, parameters, methods) begin with a lower-case letter.
  • Use descriptive names of a reasonable length.

Class Naming

  • The first letter is always an upper-case letter (An Exception IS a class).
  • The header (.h) and implementation (.cxx) files are names exactly the same as the name of the class followed by the .h or .cxx extension.
  • For any class that is an interface (all methods are virtual), the name ends with Interface.
  • For any class that is an enumerated type, the name ends with Enum.

Base Class

Each class should be derived from CaretObject or QObject. CaretObject provides a method (that can be overridden) for printing information about an object and, when compiled debug, can track allocation of objects and report those that are not deleted. QObject is a parent of all Qt classes used in the Qt graphical user-interface.

Copy Constructor and Assignment Operator

If a class instance can be copied, both the copy constructor and the assignment operator should either be fully implemented and publicly accessible. Otherwise, both should be declared, without any implementation, in a private section of the header file.

Code Organization

AVOID WRITING EXTREMELY LONG (over 100-200 lines) FUNCTIONS IF IT'S AT ALL POSSIBLE. Long blocks of code may be slightly easier to write in the very short term, but are extremely inefficient in terms of code reuse, maintenance, and adding new features.

If one has to write a very long function/method, try to group the function body into logical blocks that fit on a single page. This makes it much easier for other developers to figure out what is going on, vs. having to skip back and forth over several hundred lines. Even better, provided there are no efficiency issues, try to break very long functions into separate function calls that have descriptive names. Modular code is much easier to reuse, which is another benefit.

If there are style guidelines that are making it difficult to condense a block of code onto a single page, use your best judgement and balance the need for coding standards with concision.


Use assertions on parameters passed to a method. In particular, on any index parameters.

The assert() function takes one parameter. If the value of the parameter is zero, abort() is called and a message listing the source code file and line number is printed. The assert function is in the header <cassert>.

A special assertion is needed assertRange(value, min-value, max-value);

Auto Pointers

Auto Pointers may be useful but must be used with caution.


NEVER, NEVER use tabs. Instead, use 4 spaces (or 3?). Make sure any editor is setup to insert spaces in place of tabs.

One Line Does One Thing

Do not try to cram more than one operation on a single line. This is almost always the rule.


  • If concision allows a block to fit inside a single page, making it easier to read, then it MIGHT be better to combine short statements that are closely related.

If Statements

Always use brackets on if statements and else clauses. When code is being modified a programmer might add statement-B thinking that it is part of the then clause. Hover it it not. See example below. If you absolutely do not want to use brackets place the "then" statement on the same line after the if clause.

    if (condition)

    if (condition) {

    if (condition) statement-A;

A potential case where it DOES make sense to use a single line if statement is for things like error checking, or determining if a variable has been initialized. This helps reduce the amount of space that this kind of boiler plate uses, which increases the likelihood that a developer can fit a single logical block of code on a single page. Taking up too much space with boiler plate, while looking better, can make the code harder to understand.

Parallel Processing

Use OpenMP. The easiest way is to place the OpenMP directive on the line above a loop and have the loop consists of a single statement that calls a method.

In the User-Interface there may be cases where QThread is used.


Use the integer types from stdint.h that provide the exact size in bits (int32_t, uint64_t, etc.).

Declaring local variables and members.

  • Declare each member or local variable on its own line.
    • An exception to this is variables that are logically grouped together. i.e.
    int x,y,z,t;
  • Declare any local variables in as small a scope as possible. There are exceptions to this rule but the situation should be exceptional.
  • In addition to declaring inside (or near) the block they are relevant, try to use names that make sense so that other developers can figure out what they are being used for. i.e. temp is rarely a good name for anything.

Line Length

Beyond 80 characters is okay but try to keep it under 100.


Don't be afraid to use parenthesis in conditional or mathematical statements. They remove ambiguity and may even make the code function correctly.


While this isn't used often, don't be afraid to put sections of your code into blocks. This is especially useful for declaring temp variables that only apply to a a small area of code, as it helps to reduce the scope of variables. This is also a good first step when breaking a very large function down into a group of smaller functions. An exception is that in tight inner loops declaring variables inside the loop (or having a block with variables inside the loop) has some overhead.


When calling a method, place each parameter on a separate line. The first parameter may be on the same line as the method. The second and remaining parameters should be aligned with the first parameter (however the wiki is messing this up in the example below).

   class->methodName(firstParameter,secondParameterIsHere, andHereIsTheThirdParameter);


Implementing methods

  • Doxygen comment goes first.
  • Return type is listed on next line.
  • Class::methodName and first parameter is on next line.
  • Any remaining parameters are on the additional lines.
  • Opening bracket is on a line by itself.
  • Method body.
  • Closing bracket is on a line by itself.
 * Get a matrix element.
 * @param i   Row
 * @param j   Column
 * @return   value at [i][j]
                   const int32_t i,
                   const int32_t j) const
    return this->matrix[i][j];


All classes should be commented using Doxygen style comments (very similar or the same as JavaDoc) so that Doxygen can generate documentation in HTML or other formats.

The documentation for a class should describe the purpose of the class.

Since classes have both header (.h) and implementation files (.cxx), add documentation comments on methods only to the implementation of the method. In most cases, this will be inside the implementation file with the exception of inline or other short methods defined in the header file. For a method, describe the purpose of the method, each of its parameters, the values returned, and why an exception is thrown.

Member variables should be documented unless the member's name clearly describes its contents.

Use JavaDoc style commenting which begins with /** and ends with */. If the comment spans more than one line, begin each line with an asterisk.

Example Header File

 * A 4x4 homogeneous transformation matrix.
class Matrix4x4 : public CaretObject {



    double getMatrixElement(
                    const int32_t i,
                    const int32_t j) const;

    void writeAsXML(XmlWriter& xmlWriter) throw (XmlException);

    /**the 4x4 matrix */
    double matrix[4][4];

Example Implementation File

 * constructor that creates an identity matrix.
    : CaretObject()

 * Destructor

 * Get a matrix element.
 * @param i   Row
 * @param j   Column
 * @return   value at [i][j]
                   const int32_t i,
                   const int32_t j) const
    return this->matrix[i][j];

 * Write the metadata in GIFTI XML format.
 * @param xmlWriter The XML Writer.
 * @throws XmlException if an error occurs while writing.
Matrix4x4::writeAsXML(XmlWriter& xmlWriter) throw (XmlException)

Personal tools
Sums Database