Skip to content

Commit

Permalink
Revise coding guidelines
Browse files Browse the repository at this point in the history
  • Loading branch information
bernhardmgruber committed Jan 23, 2024
1 parent a0f5398 commit 5f317b8
Showing 1 changed file with 27 additions and 92 deletions.
119 changes: 27 additions & 92 deletions docs/source/dev/style.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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 <sourcefile>
* 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
<https://devblogs.microsoft.com/cppblog/clangformat-support-in-visual-studio-2017-15-7-preview-1/>`.
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<int I, typename TParam, typename TArgs...>
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<typename T, typename TSfinae = void>
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.

0 comments on commit 5f317b8

Please sign in to comment.