STAIR Vision Library Coding Guidelines
Software is written for people, not for machines.
Overview
The key to a successful (large) programming project, like any other
projects, involves planning, management, and testing. The amount of
time, effort and emphasis placed on each of these three components
depends on the size of the project and experience of the people
involved. Consistency in design and implementation is also key to
success and is what we will address in this document by outlining some
(fairly standard) coding conventions. These conventions will make the
project more manageable over time especially when many different
people are involved. The guidelines are predominantly aimed at C/C++
projects.
It is absolutely guaranteed that some users will not like the style
guidelines, and that others will even hate them. Everyone has their
own style which they prefer to use on their own projects. But even
though this is so, please understand that your team-mates, as well as
yourself, will benefit greatly from the uniformity which they offer.
Finally, since the STAIR Vision Library is designed to be
platform-independent, it is essential that you make don't implement
any platform specific functionality. Following these guidelines will
help reduce the amount of incompatibility introduced by developing in
multiple environments. Also before writing a new class or function,
check to see whether one already exists that does what you want, or
nearly what you want. Can that function be generalized to meet your
needs.
Guidelines
Source Control
- Always use a source/revision control system. Some good packages include svn (free) and Perforce (commercial). In this project we use svn.
- Check-in all code and configuration files necessary for rebuilding a project from a clean environment. Do not check-in files that can be regenerated.
- In direct contradiction to the above, it is sometimes useful to check-in (non-standard) external packages that the project requires.
- Don't forget to add new source and header files before doing a commit.
- The latest code checked into the repository is assumed to be correct. Always make sure you merge your code with the latest revision before checking in. If you're working on something experimental then create a separate branch which you can merge later.
- Always make sure your code compiles and passes any regression tests before checking-in. Remember if you break something it's likely to affect a lot of other people.
- Check-in code regularly. Don't be afraid to check-in small changes.
- Add comments when you check-in code. This will help people understand what you were trying to do when they check-out your code and it doesn't work.
Structure
- Always include a header comment at the top of each file. The header should include the name of the project, name of the file, sometimes a copyright notice, and most importantly your name and email address.
- Group the declaration of public and private members. Separate the declaration of methods from variables.
- Likewise, group common header files together, starting from standard headers (e.g., stl) through to project specific headers.
- Declare constructors and destructors before other methods.
- Declare like-functions together.
- Always implement functions in the same order in which they are declared in header files or in the prototype section at the top of the file.
- Code should be implemented in .cpp files not .h files. Exceptions are templated and short inline functions.
- Name a file the same as the class that it implements. It is okay to implement multiple classes in the same file if they logically belong together. In this case find a filename the is appropriate to the group of classes.
Variable and Object Naming
- Use all-caps for constants and macros.
- All variables should be named starting with a lowercase letter.
- Prepend an underscore to private data members.
- Prepend 'b' to boolean types, 'g' to global types.
- Descriptive variable names are strongly preferred to compactified names. Exceptions are allowed for standard technical equations. For example, to evaluate a quadratic equation it is acceptable to write y = a * x * x + b * x + c;.
- Single letter variables should be restricted to either loop iterators (preferably i, j, or k), or terms in very local computations (i.e., it is okay to use 'x' in a computation only if the scope of 'x' is less than a few dozen lines of code at the most).
- All STAIR Vision Library classes should begin with svl.
Comments
- It is a waste of time to write software without comments! Your comments don't need to be lengthy, but they should be informative.
- Make sure you update your comments whenever you change your code.
Portability and Maintainability
- Never use variable or object names that could be keywords under different systems (e.g. min, max, win, file).
- Use standard libraries (available on all platforms)---in particular, the stl. Don't reinvent the wheel.
- Keep object interfaces short and simple, it will make it much easier for other people to learn and use.
- When composing stl datatypes make sure you put a space between the > characters, for example vector<vector<double> >. Some compilers will (correctly) interpret >> as an operator and will generate an error.
- Some compilers like to have a blank line at the end of all source files. If you're working in multiple environments then it is good practice to do this.
- Set your editor to replace tabs with spaces.
- Do not have two (or more) file names that differ only in their character case---for one thing this will confuse SVN under Windows.
Performance
- Don't copy large data structures around. Rather pass by reference (&) or by pointer (*).
- Use const whenever you can.
- Avoid allocating and deallocating memory in tight loops---rather allocate all the memory you need outside of the loop, but don't forget to deallocate the memory eventually.
- Don't use printf's (or output stream operators) in tight loops.
- Use reserve to allocate memory to vector's and other stl datatypes before populating.
Miscellaneous
- Avoid using #define when you can use a const variable or enum instead.
- Use structures, unions and classes to keep related variables together.
- Limit the use of global and static variables.
- Enclose conditionally executed code in braces (e.g., after an if or for statement) even if the code is only a simple statement. This will prevent bugs later on when you modify the code.
Testing
- Write and use regression tests.
- Make sure your code compiles without any compiler warnings.
- If you discover a (non-trivial) bug, first write a simple test that exposes the bug, before debugging. Then add the test to your regression test suite.
- Use lots of assert()'s. You can always compile them out for speed later.
- Run you code while watching system memory (Task Manager under Windows or top under Linux) to identify memory leaks.
- If you have a bug, first think about where in the design the bug could be, before jumping into the code.
Copyright © 2007-2009, Stephen Gould.