diff --git a/docs/source/dev/style.rst b/docs/source/dev/style.rst index c95bfc5b51db..f7e2902ea5a6 100644 --- a/docs/source/dev/style.rst +++ b/docs/source/dev/style.rst @@ -3,148 +3,83 @@ Coding Guidelines ================== -.. attention:: - The Coding Guidelines are currently revised +Formatting +---------- -General -------- - -* Use the ``.clang-format`` file supplied in alpaka's top-level directory to format your code. This will handle indentation, -whitespace and braces automatically. Usage: - -.. code-block:: bash - - clang-format-16 -i - -* If you want to format the entire code base execute the following command from alpaka's top-level directory: - -.. code-block:: bash - - find example include test -name '*.hpp' -o -name '*.cpp' | xargs clang-format-16 -i - -Windows users should use `Visual Studio's native clang-format integration -`. +Use the ``.clang-format`` file supplied in alpaka's top-level directory to format your code. +This will handle indentation, whitespace and braces automatically. +Checkout ``CONTRIBUTING.md`` on how to run it. Naming ------ * Types are always in PascalCase (KernelExecCuda, BufT, ...) and singular. -* Variables are always in camelCase (memBufHost, ...) and plural for collections and singular else. +* Variables are always in camelCase (memBufHost, ...) and singlar by default. Use plural for collections. * Namespaces are always in lowercase and singular is preferred. -* There are no two consecutive upper case letters (AccOpenMp, HtmlRenderer, IoHandler, ...). This makes names more easily readable. - - -Types ------ - -* Always use integral types with known width (``int32_t``, ``uint64_t``, ...). - Never use ``int``, ``unsigned long``, etc. - +* Avoid consecutive upper case letters. E.g.: AccOpenMp instead of AccOpenMP, or HtmlRenderer instead of HTMLRenderer. + This makes names more easily readable. Type Qualifiers --------------- -The order of type qualifiers should be: +The order of type qualifiers should be: ``Type const * const`` for a const pointer to a const Type. ``Type const &`` for a reference to a const Type. The reason is that types can be read from right to left correctly without jumping back and forth. ``const Type * const`` and ``const Type &`` would require jumping in either way to read them correctly. +clang-format should handle this automatically in most cases. Variables --------- -* Variables should always be initialized on construction because this can produce hard to debug errors. - This can (nearly) always be done even in performance critical code without sacrificing speed by using a functional programming style. -* Variables should (nearly) always be ``const`` to make the code more easy to understand. - This is equivalent to functional programming and the SSA (static single assignment) style used by LLVM. - This should have no speed implication as every half baked compiler analyses the usage of variables and reuses registers. -* Variable definitions should be differentiated from assignments by using either ``(...)`` or ``{...}`` but never ``=`` for definitions. - Use ``uint32_t const iUsageOfThisVariable(42);`` instead of ``uint32_t const iUsageOfThisVariable = 42;`` - +* Variables should be initialized at definition to avoid hard to debug errors, even in performance critical code. + If you suspect a slowdown, measure first. +* Variables should be ``const`` to make the code more easy to understand. + This is equivalent to functional programming and the SSA (static single assignment) style. +* Prefer direct-initialization using braces for variable definitions, e.g. ``T t{...}``, + over copy-initialization, e.g. ``T t = {...}``. + Avoid direct-initialization using parenthesis, e.g. ``T t(...)``. Comments -------- -* Always use C++-Style comments ``//`` -* For types use - ``//#############################################################################`` - to start the comment block. -* For functions use - ``//-----------------------------------------------------------------------------`` - to start the comment block. - +* Always use C++-style comments ``//`` Functions --------- -* Always use the trailing return type syntax with the return type on a new line even if the return type is void: +* Always use the trailing return type syntax, even if the return type is ``void``: .. code-block:: - auto func() - -> bool + auto func() -> bool -* This makes it easier to see the return type because it is on its own line. * This leads to a consistent style for constructs where there is no alternative style (lambdas, functions templates with dependent return types) and standard functions. -* Each function parameter is on a new indented line: - -.. code-block:: - - auto func( - float f1, - float f2) - -> bool - { - return true - } - -.. code-block:: - - func( - 1.0f, - 2.0f); - -* Makes it easier to see how many parameters there are and which position they have. - Templates --------- -* Template parameters are prefixed with ``T`` to differentiate them from class or function local typedefs. -* Each template parameter is on a new indented line: +* Template parameters, which are not a single letter, are prefixed with ``T`` to differentiate them from class or function local aliases. .. code-block:: c++ - template< - typename TParam, - typename TArgs...> - auto func() - -> bool + template + auto func() -> bool -* Makes it easier to see how many template parameters there are and which position they have. -* Always use ``typename`` for template parameters. There is NO difference to class and typename matches the intent better. +* Always use ``typename`` instead of ``class`` for template parameters. + There is NO semantic difference between them, but ``typename`` matches the intent better. Traits ------ -* Trait classes always have one more template parameter (with default parameter) then is required for enabling SFINAE in the specialization: +* Trait classes must have one additional template parameter (defaulted to ``void``) then required to enable SFINAE in specializations: .. code-block:: - template< - typename T, - typename TSfinae = void> + template struct GetOffsets; -* Template trait aliases always end with a ``T`` e.g. ``BufT`` while the corresponding trait ends with ``Type`` e.g. ``BufType`` * Traits for implementations always have the same name as the accessor function but in PascalCase while the member function is camelCase again: ``sin(){...}`` and ``Sin{sin(){...}};`` - -Includes --------- - -* The order of includes is from the most specialized header to the most general one. - This order helps to find missing includes in more specialized headers because the general ones are always included afterwards. -* A comment with the types or functions included by a include file make it easier to find out why a special header is included.