Rule A7-5-2 (required, implementation, automated)
Functions shall not call themselves, either directly or indirectly.
Rationale
As the stack space is limited resource, use of recursion may lead to stack overflow at run-time. It also may limit the scalability and portability of the program. Recursion can be replaced with loops, iterative algorithms or worklists.
Exception
Recursion in variadic template functions used to process template arguments does not violate this rule, as variadic template arguments are evaluated at compile time and the call depth is known. Recursion of a constexpr function does not violate this rule, as it is evaluated at compile time.
Example
// $Id: A7-5-2.cpp 289436 2017-10-04 10:45:23Z michal.szczepankiewicz $
#include <cstdint>
static std::int32_t Fn1(std::int32_t number);
static std::int32_t Fn2(std::int32_t number);
static std::int32_t Fn3(std::int32_t number);
static std::int32_t Fn4(std::int32_t number);
std::int32_t Fn1(std::int32_t number)
{
if (number > 1)
{
number = number * Fn1(number - 1); // Non-compliant
}
return number;
}
std::int32_t Fn2(std::int32_t number)
{
for (std::int32_t n = number; n > 1; --n) // Compliant
{
number = number * (n - 1);
}
return number;
}
std::int32_t Fn3(std::int32_t number)
{
if (number > 1)
{
number = number * Fn3(number - 1); // Non-compliant
}
return number;
}
std::int32_t Fn4(std::int32_t number)
{
if (number == 1)
{
number = number * Fn3(number - 1); // Non-compliant
}
return number;
}
template <typename T>
T Fn5(T value)
{
return value;
}
template <typename T, typename... Args>
T Fn5(T first, Args... args)
{
return first + Fn5(args...); // Compliant by exception - all of the
// arguments are known during compile time
}
std::int32_t Fn6() noexcept
{
std::int32_t sum = Fn5<std::int32_t, std::uint8_t, float, double>(
10, 5, 2.5, 3.5); // An example call to variadic template function
// ...
return sum;
}
constexpr std::int32_t Fn7(std::int32_t x, std::int8_t n)
{
if (n >= 0)
{
x += x;
return Fn5(x, --n); // Compliant by exception - recursion evaluated at
// compile time
}
return x;
}
See also
MISRA C++ 2008 [7]: Rule 7-5-4 Functions should not call themselves, either directly or indirectly. JSF December 2005 [8]: AV Rule 119 Functions shall not call themselves, either directly or indirectly (i.e. recursion shall not be allowed). HIC++ v4.0 [9]: 5.2.2 Ensure that functions do not call themselves, either directly or indirectly.