Skip to content

Coding guide lines

Olof Kallander edited this page Aug 5, 2022 · 12 revisions

Keep it simple. Prefer simple, elegant solution. Performance sensitive code usually has an elegant solution too, if you look for it.

Decoration

  • Use camel case always.
  • Namespaces in lower case only. Nest them on words.
  • Class / type names start with upper case, everything else starts with lower case
  • Prefer constants in capital and snake case. MAX_INT
  • Prefix private member variables with _
  • Do NOT prefix public member variables, especially in passive structs as most code will use these directly and it improves readability of that code
  • Do NOT use type prefixes like i, sz, u, p.

Naming

  • Avoid abbreviations
  • Use as short names as possible but convey as much meaning as possible and be specific
  • Avoid generic meaningless names like DataInfo

Comments

Let the code speak for itself. Code comments is a sign of failure to clearly express in code what the computer is supposed to do. If you have to chatter through the code what each line is doing, there is something wrong with the code. It breaks up the readers focus on the code and may even mislead the reader to belive the code does what the comment says, not what the code actually does. It is a risk that the code actually does not do what you intend if you cannot read it as is. Before you place a comment, ask yourself if you have done everything you can to name variables and methods well, breaking down the problem into smaller, well named methods. Usually, the code speaks for itself and becomes much more readable once you have done that.

That said, code comments can be necessary to give hints about unexpected meaning or behaviour that is internal or external to the code. Preferrably place those comments above the class or method as to keep it out of the readers eyes when reading the code. As a last resort, place the comment in the code.

Structure

  • Let clang format the code according to format file
  • Use proximity principle for related and dependant methods and types
  • Group related member variables into sub structs to clarify semantics and reduce code in main class constructor.
  • Break down code blocks into well named smaller methods that will tell the reader what the code does
  • Break down complex conditions and store in temporary bool variables that convey meaning and tells reader what is being decided or calculated
  • Avoid automatic type conversions and declare single parameter constructors as explicit
  • Use auto when possible for local variables if it reduces use of long type names or templates
  • Do not override or define operators except for -> and +,-,* for certain types
  • Use lambdas with discretion. They can be powerful and make code more readable, but sometimes a plain loop may be more clear.
  • Provide begin, end, on datastructures to facilitate iteration with for(a : data), if meaningful.
  • Declare variables close usage and late. Static variables in functions can be an alternative to global, or class global variables.
  • Always use {} for block after branch like if, while, for, etc. Even if it is a single line.
  • Use forward declaration in header files instead of includes, whenever possible.
  • Use & parameter in preference to *. Use only * if there is a need for passing a nullptr, passing ownership.
  • Enclose rhs in braces in assignment if it contains equality operators. Eg. v = (a == b ? d:e) and b = (t == 5).

Threading

SMB separates between real time code and API level code. MixerManager thread and http server threads are considered normal priority context. All other threads are considered real time. The engine thread is time critical and runs on elevated priority.

  • Mutexes are only allowed at API level code.
  • Memory allocation is only allowed at API level
  • Execution in the real time code must rely on the wait free queues and serializing jobs to proper job queue to facilitate serialization of operations and synchronization.
  • Exceptions are not allowed in real time contexts. You cannot use STL methods that may throw exceptions at RT level. Exceptions are allowed at API level.

Logging

Do not spam

  • error, warn levels means unrecoverable problem, recoverable problem
  • info is for events that happen about once every call and are of significant importance
  • debug, the rest.
Clone this wiki locally