1.. title:: clang-tidy - readability-function-cognitive-complexity
2
3readability-function-cognitive-complexity
4=========================================
5
6Checks function Cognitive Complexity metric.
7
8The metric is implemented as per the `COGNITIVE COMPLEXITY by SonarSource
9<https://www.sonarsource.com/docs/CognitiveComplexity.pdf>`_ specification
10version 1.2 (19 April 2017).
11
12Options
13-------
14
15.. option:: Threshold
16
17   Flag functions with Cognitive Complexity exceeding this number.
18   The default is `25`.
19
20.. option:: DescribeBasicIncrements
21
22   If set to `true`, then for each function exceeding the complexity threshold
23   the check will issue additional diagnostics on every piece of code (loop,
24   `if` statement, etc.) which contributes to that complexity. See also the
25   examples below. Default is `true`.
26
27.. option:: IgnoreMacros
28
29   If set to `true`, the check will ignore code inside macros. Note, that also
30   any macro arguments are ignored, even if they should count to the complexity.
31   As this might change in the future, this option isn't guaranteed to be
32   forward-compatible. Default is `false`.
33
34Building blocks
35---------------
36
37There are three basic building blocks of a Cognitive Complexity metric:
38
39Increment
40^^^^^^^^^
41
42The following structures increase the function's Cognitive Complexity metric
43(by `1`):
44
45* Conditional operators:
46
47   - ``if()``
48   - ``else if()``
49   - ``else``
50   - ``cond ? true : false``
51
52* ``switch()``
53* Loops:
54
55   - ``for()``
56   - C++11 range-based ``for()``
57   - ``while()``
58   - ``do while()``
59
60* ``catch ()``
61* ``goto LABEL``, ``goto *(&&LABEL))``,
62* sequences of binary logical operators:
63
64   - ``boolean1 || boolean2``
65   - ``boolean1 && boolean2``
66
67Nesting level
68^^^^^^^^^^^^^
69
70While by itself the nesting level does not change the function's Cognitive
71Complexity metric, it is tracked, and is used by the next, third building block.
72The following structures increase the nesting level (by `1`):
73
74* Conditional operators:
75
76   - ``if()``
77   - ``else if()``
78   - ``else``
79   - ``cond ? true : false``
80
81* ``switch()``
82* Loops:
83
84   - ``for()``
85   - C++11 range-based ``for()``
86   - ``while()``
87   - ``do while()``
88
89* ``catch ()``
90* Nested functions:
91
92   - C++11 Lambda
93   - Nested ``class``
94   - Nested ``struct``
95* GNU statement expression
96* Apple Block Declaration
97
98Nesting increment
99^^^^^^^^^^^^^^^^^
100
101This is where the previous basic building block, `Nesting level`_, matters.
102The following structures increase the function's Cognitive Complexity metric by
103the current `Nesting level`_:
104
105* Conditional operators:
106
107   - ``if()``
108   - ``cond ? true : false``
109
110* ``switch()``
111* Loops:
112
113   - ``for()``
114   - C++11 range-based ``for()``
115   - ``while()``
116   - ``do while()``
117
118* ``catch ()``
119
120Examples
121--------
122
123The simplest case. This function has Cognitive Complexity of `0`.
124
125.. code-block:: c++
126
127  void function0() {}
128
129Slightly better example. This function has Cognitive Complexity of `1`.
130
131.. code-block:: c++
132
133  int function1(bool var) {
134    if(var) // +1, nesting level +1
135      return 42;
136    return 0;
137  }
138
139Full example. This function has Cognitive Complexity of `3`.
140
141.. code-block:: c++
142
143  int function3(bool var1, bool var2) {
144    if(var1) { // +1, nesting level +1
145      if(var2)  // +2 (1 + current nesting level of 1), nesting level +1
146        return 42;
147    }
148
149    return 0;
150  }
151
152In the last example, the check will flag `function3` if the option Threshold is
153set to `2` or smaller. If the option DescribeBasicIncrements is set to `true`,
154it will additionally flag the two `if` statements with the amounts by which they
155increase to the complexity of the function and the current nesting level.
156
157Limitations
158-----------
159
160The metric is implemented with two notable exceptions:
161   * `preprocessor conditionals` (``#ifdef``, ``#if``, ``#elif``, ``#else``,
162     ``#endif``) are not accounted for.
163   * `each method in a recursion cycle` is not accounted for. It can't be fully
164     implemented, because cross-translational-unit analysis would be needed,
165     which is currently not possible in clang-tidy.
166