Skip to content

Coding Philosophy and Guidelines

François Beaune edited this page Jul 18, 2018 · 21 revisions

This document summarizes the coding guidelines in appleseed. This is a perpetual work in progress.

Philosophy

  • We believe in collective code ownership. All the code belongs to everyone. Feel free to fix or improve any part of the code.

  • We believe in continuous refactoring. If you come across something that you feel is not as good as it could be (be it code, documentation, test data...) make a note to yourself or open an issue in the tracker and come back to it later, or improve it right away.

  • We believe in clean code. Code quality and readability is of utmost importance. Choose your class, method and variable names carefully, keep the code concise, respect the coding conventions, pay attention to formatting and to the order of declarations, etc.

  • We believe in code reviews. We need to share the knowledge of the code, and make sure it is as good as it can possibly be. We'll ask you to review our code and we'll review yours.

  • We believe in fearless coding. Don't get scared of experimenting and hacking your way around. Unit tests, integration tests and Git are all here to make sure you don't break things.

  • For documentation like for code: don't repeat yourself.

  • Know when to break these rules. Software development cannot be reduced to a strict set of rules. Be measured and reasonable.

Language

We are using C++11 throughout the code base.

Naming Conventions

  • Namespaces: a single (preferably short) word in lower case
    • excepted for namespaces hiding implementation details in header files: in this case, add a _impl suffix: namespace thread_impl.
  • Types, enums, unions, structs, classes, public constants: CamelCaps.
  • Functions, variables, class methods and members:
    • lower case, words separated with underscores
    • global variables: g_ prefix
    • class members: m_ prefix
      • excepted in the following classes: foundation::Vector, foundation::Matrix, foundation::Color and foundation::AABB
      • excepted for private implementation (impl).

Coding Style

#include statements

Group #include statements by category (in this order):

  1. In .cpp files, start by including the matching header file.
  2. Then comes appleseed.renderer header files, if any.
  3. Then appleseed.foundation header files, if any.
  4. Then header files from third party libraries, if any.
  5. Then standard header files.

Within each category, keep all #include statements ordered alphabetically.

Usage of struct and class

Use struct only for trivial classes, otherwise stick to class, even if all members are public. The goal is to simplify forward declarations, where it is mandatory to use the same keyword (struct or class) as in the definition.

inline keyword

In general, don't declare functions/methods inline, but define them as inline.

const keyword

Use const copiously. Everything that can be const should be const, including integral parameters of functions and methods.

override keyword

When overriding a virtual methods, always tag the method with override. Don't repeat virtual for overriden methods.

Comments

  • Comments on their own lines start with a capital letter and end with a period.
  • Comments on the same line as code start with a lower case letter and don't end with a period.

Formatting

Source Files

  • Header files must have a .h extension and source files must have a .cpp extension.
  • All header and source files must begin and end with an empty line.
  • All header and source files must contain an up-to-date copyright notice.

Indentation

  • Tab size 4, indent 4, tabs as spaces.
  • Curly braces on their own line.
  • Keywords public, protected and private indented with two spaces.
  • Preprocessor directives such as #ifdef, #endif, #pragma, etc. must be left-aligned (no indentation).
  • Namespaces: the contents of all namespaces (including anonymous namespaces) must be indented, except for top-level namespaces where that would result in the entire file being indented, wasting a level of indentation without any benefit.

Spacing

  • Operators + - * / % = == != < > <= >=
    • surrounded by spaces
    • excepted after 'operator' keyword.
  • References and pointers: int& x, int* p.
  • No spaces around brackets.
  • No spaces around parentheses, excepted after control flow keywords (if for while do).
  • No space before commas, one space after commas: int x, y;
  • No space between delete and []: delete[] array;
  • During definition, template <...> statements go on their one line.

Header Files and Forward Declarations

Whenever possible, forward declarations are preferred.

We follow the IWYU ("Include What You Use") rule. This rule states that every C++ source file (.h and .cpp) must include all header files it relies on, even if those already included indirectly via other header files.

The only exception is that .cpp files must not repeat includes already present in their "interface" header file, i.e. foo.cpp must not repeat includes from foo.h.

The IWYU rule, or at least the term, was popularized by Google via their iwyu tool: https://include-what-you-use.org/

User Interfaces

As far as possible, we are following Apple Human Interface Guidelines.

Clone this wiki locally