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