meta data for this page
The coding style for Itlab CPP Library
Names
- class names
- camel-case, starting with capital letter; example: BayerImage
- methods
- camel-case, starting with small letter; example: getUCharP()
- attributes (member variables)
- camel-case, starting with small letter, ending with underscore; srcImg_
- local variables
- camel-case, starting with small letter.
- templates
- template classes as normal classes, template functions/methods as normal functions/methods.
- macros
- all-caps; example: #define FW_BUS_ID(i) (0x1002380+(i)*0x10)
- simple types in typedefs
- camel-case, starting with small letter, ending with _t; example: typedef int handle_t
- structs
- camel-case, starting with small letter; example: struct fPoint3
Structs may not contain member functions (methods), and are usually not typedef'd.
Do not use Hungarian notation (for instance pszName
meaning pointer to zero-terminated string). Instead, add documentation to where your variables are declared.
Use the proper variable names in function declarations in headers, it helps understanding the interface by reading the header file. And the names should be descriptive, not a single letter nor misleading.
- implementation files
- class name with .cc extension.
- header files
- class name with .hh extension.
- template files
- class name with .hh extension.
Indentation and Lines
Use only tabs for block indenting, not spaces. Tab width is 8 characters for computing line lengths.
Maximum line length is 79 characters. This may feel too deep indentation, but when you are doing more than 5 levels of indenting, think about if it should be broken into functions. An exception are switch..case
sections, which can be indented as following:
Image & createImage(enum imtype t) { switch(t) { case TYPE_RGB: return RGBImage(); case TYPE_GRAY: return GrayImage(); default: throw std::invalid_argument("Unknown image type."); } }
Alignment, which is not block indenting, must be done with spaces. Tabs can be used only as the first characters of a line (Reasoning: http://mcf.ath.cx/Docs/libmcf/CodeStyle.html ).
Long function declarations and long function calls are indented by alignment (if at all possible, sometimes line length may prevent this):
ret = object.dummyFunction(img->height(), img->width(), img->depth(), img->getUCharP(), TYPE_RGB);
Currently, it seems that “bsd” indentation style in Emacs gives the desired indentation. Set that with C-c . bsd <ret>. After that you can indent the current function using C-c C-q or a marked region by M-x indent-region. You can also make the style setting automatically per file by inserting the following as the first line of the file:
/* -*- c-file-style: "bsd" -*- */
Write only one statement on a line.
Blocks
The opening and closing curly braces {} must be at the same indentation level. Examples:
void dummy(int cnt) { int i = 0; do { ++i; } while(i<cnt); if(cnt > 10) { std::cout << "That was long." << std::endl; i = 10; } else { std::cout << "Short!" << std::endl; } }
Documentation
Use Doxygen documentary comments.
Short documentation can be in header files as ///
and ///<
comments, longer documentations for methods in implementation files, for instance:
/** @brief Query information about a video channel. * * You have to allocate a struct video_channel yourself for calling * this function. * @pre The device must be opened. * @param[[out]] vc Structure for returning channel information. * @param[[in]] chan The channel number, starting from 0. * @throw GenError The channel number was out of range. * @throw StdError Querying channel properties failed. * @sa print_channel_info(), channel(), channels(), set_channel() */ void Videodev::channel_info(struct video_channel * const vc, const int chan) const throw (GenError) {
And an example of the shorter comments:
/// List of video palettes in V4L, see the list in %Videodev.cc source. static struct tag_palettes { const int palette; ///< palette id as in V4L const char *str; ///< palette name (e.g. in configs) const char *desc; ///< short description, for the user } palettes[[]];
Long class documentation must be put in the header files right before class declaration. Having method documentation in implementation files makes the class declaration shorter and easier to read. Of course, these rules may need to be bent for template classes and implementations in header files.
Coding guidelines
As said, these are general guidelines that should be adhered to whenever possible.
- Never put a
using
statement in a header file. Users do not expect that including a header might mess with the default namespace. - When you
#include
a file in a public library header, always use<>
notation. - In other cases, when you
#include
a file, put the name in double quotes (“”
) only, if the header is in the current directory. All other times use angle brackets (<>
) - In library headers, do not #include another header file if a simple forward declaration suffices.
- Prefer to use
std::string
instead of char arrays and char pointers. - Prefer the standard exception classes from
stdexcept
. If you need a stack trace to be recorded into the exception, you may considerGenError
andStdError
from Utils. - Do use exceptions for exceptional errors, but never as a part of normal expected program execution flow.
- Do use the
const
keyword:- method return types (pointers and references)
- method parameters
- methods (i.e. const method of a class)
- varibles and attributes (e.g.
const ObjectClass * const fooptr
)
- Never call
exit()
on error, throw an exception instead. - Try to keep interfaces simple and minimal.
Examples
GLPixelBufferObject
itlab/itlabcpp/base/src/GLGraphics/GLPixelBUfferObject.hh
is an example of how to use the coding style for writing a template class. It demonstrates the license, using C-headers, documenting with Doxygen, and other coding style issues, which may not have been defined here, but are a good practice. Notable things are documenting the use quirks properly (in writeToTexture()
) and denying default constructor, copy constructor and assignment operator when they are not expected.
Hints
- Using
snprintf
on astd::string
is impossible (is it?), try to usestd::ostringstream
from IOstream library instead.