This rule is part of MISRA C++:2023.
Usage of this content is governed by Sonar’s terms and conditions. Redistribution is
prohibited.
Rule 8.2.10 - Functions shall not call themselves, either directly or indirectly
Category: Required
Analysis: Undecidable,System
Rationale
Recursion carries with it the danger of exceeding available stack space, which can lead to a serious failure. Unless recursion is very tightly
controlled, it is not possible to determine before execution what the worst-case stack usage could be.
Note: any deviation used to justify non-compliance with this rule will need to explain how stack usage is to be controlled.
Exception
A constexpr function that is only called within a core constant expression may be recursive.
Example
int32_t fn( int32_t x )
{
if ( x > 0 )
{
x = x * fn( x - 1 ); // Non-compliant
}
return x;
}
// File1.cpp
int32_t fn_3( int32_t x );
int32_t fn_2( int32_t x )
{
if ( x > 0 )
{
x = x * fn_3( x - 1 ); // Non-compliant
}
return x;
}
// File2.cpp
int32_t fn_2( int32_t x );
int32_t fn_3( int32_t x )
{
if ( x > 0 )
{
x = x * fn_2( x - 1 ); // Non-compliant
}
return x;
}
In the following, the recursion within fn_4 satisfies the requirements of the exception as it is only called from
within a core constant expression.
constexpr int32_t fn_4( int32_t x )
{
if ( x > 0 )
{
x = x * fn_4( x - 1 ); // Compliant by exception
}
return x;
}
constexpr int32_t n = fn_4( 6 ); // Core constant expression
constexpr int32_t fn_5( int32_t x )
{
if ( x > 0 )
{
x = x * fn_5( x - 1 ); // Non-compliant
}
return x;
}
int32_t n = fn_5( 6 ); // Not a core constant expression
template< class T >
auto Sum( T t )
{
return t;
}
template< class T, class ... Vals >
auto Sum( T t, Vals ... vals )
{
return t + Sum( vals ... ); // Compliant - calls a different overload
}
Copyright The MISRA Consortium Limited © 2023