To maintain the complexity and usability of this project’s code, this guide outlines coding and style rules that should be followed when contributing, along with suggested pointers. This guide borrows a large part from the Google C++ Style Guide. It is a much shorter guide that emphasizes key rules that should be followed for Trodes.
This guide is for general practices for coding in Trodes. More detailed implementations and design specifics, such as topics related to communication and QT, are defined elsewhere.
Namespaces are defined for major functional modules that contain multiple class instantiations, such as unique processes and custom shared libraries. No variables in the global scope are ever allowed, while non-member variables within namespaces are okay, but discouraged. Explicit passing of parameters/messages, pointers to shared memory, objects between namespaces should be used. Abstractions such as QT signals/slots use are encouraged where appropriate.
Each process must have it’s own unique namespace.
Never use the directive.
Trodes should only require two levels of namespaces, no more. Top level namespace should cover shared libraries and independent processes. Second level namespace are reserved for submodules within processes for organizational purposes.
Static and Global Variables¶
Global and namespace scope static and global object variables that have any form of dynamic initialization or destruction are forbidden. Only classes that can be expressed using (a C++11 specifier) are allowed to be in a global namespace. This is because order of initialization and destruction is not guaranteed between translational units. With namespaces that can span multiple translational units and multiple threads, this can cause difficult to debug errors.
Global scope global and static primative variables are also forbidden. This is to aid in reading, tracing and debugging code that can uses shared implementations across threads and processes.
Namespace scope global and static primative variables are allowed, but discouraged, primarily due to readability and debugging concerns.
Otherwise no explicit liminations for variable definitions and scope.
Nested/member classes should typically be private, unless they are an interface used by external methods. Keep public member classes out of the global scope by using namespaces.
Avoid predefining variables before they are used, keep declarations in the closest possible scope and near where it is being used. Make sure to consider object variables that get constructed everytime it enters a scope and destructed everytime it leaves. In general this helps improve readability.
One Parameter Constructors¶
All one parameter constructors should be defined at explicit.
Work in Constructor¶
Best practice is to keep operations in constructors at a minimum. Keep any error prone code out of constructors to prevent errors/failures that could leave the object in an indeterminate state.
Hiearchical and complex inheritance schemes should not be used. It makes code less readable and there’s almost always better ways to structure your code.
Also consider using the composition model as an alternative to inheritance.
Member variables should be private and the class should provide accessors and mutators as needed.
Try to keep functions short and modular. Break up large functions if possible. A guideline is if a function is 40 lines or greater, rethink whether or not it can be broken up.
Other C++ Features¶
Don’t use preprocessor macros, instead consider using inline functions, enums, and const variables.
Coding Style Rules¶
Variable, Function and Class Names¶
The main convention use is a form of camelcase. Variable and function names should begin with a lowercase and the remaining follow upper camelcase (for all following words and abbreviations the first level is capitalized with no deliminator between words). Class names and similar definitions are should always begin with a capital letter and follow upper camelcase rules.
Practically, because Trodes is multiprocess and namespaces should be modular with well defined interfaces, it’s okay for other modules/plugins to have different style rules. For example code written in pure C or written in python can follow styles that are more commonly used in their languages.
The main rule to follow is to try to be consistent within a related module of code. This helps keep things readable and hopefully flexible.