Why is this an issue?
This is a draft version of a MISRA C++ 202x rule proposed for public review.
MISRA Rule 28.6.2
Category: Required
Analysis Type: Decidable,Single Translation Unit
Amplification
A forwarding reference parameter (of type T &&
) shall be forwarded when passed to other functions by wrapping the
parameter in a call to the function std::forward< T >
.
Furthermore, std::forward
shall only be used to forward a forwarding reference.
Rationale
Perfect forwarding relies on language features such as reference collapsing and type deduction which are complex to master. Enforcing the use of
well known idioms avoids the risk of writing code that does not do what was intended.
Note: care must be taken not to forward the same argument twice — see M23_280: MISRA C++ 2023 Rule 28.6.3.
Example
void f1( std::string & ); // #1
void f1( std::string && ); // #2
template< typename T1, typename T2 >
void f2( T1 && t1, T2 & t2 )
{
f1( t1 ); // Non-compliant - calls #1
f1( std::forward< T1 >( t1 ) ); // Compliant - calls #1 (for #4) or #2 (for #3)
f1( std::forward< T2 >( t2 ) ); // Non-compliant - calls #2
f1( std::forward< T2 >( t1 ) ); // Non-compliant - wrong template parameter
f1( std::move( t1 ) ); // Non-compliant - calls #2
f1( std::move( t2 ) ); // Rule does not apply - calls #2
auto lambda = [] ( auto && t )
{ f1(t); }; // Non-compliant - calls #1
}
void f3()
{
std::string s;
f2( std::string { "Hello" }, s ); // #3
f2( s, s ); // #4
}
template< typename T >
struct A
{
void foo( T && t )
{
std::move( t ); // Rule does not apply - not a forwarding reference
}
};
Copyright The MISRA Consortium Limited © 2023
Resources
Related rules
- S5425 detects when a parameter of forwarding reference type is never used in a
std::forward
call
- S5417 ensures that
std::forward
is not confused with std::move
- S6031 reports when the incorrect template parameter is provided to std::forward
- M23_280: MISRA C++ 2023 Rule 28.6.3 ensures that a parameter is never moved or forwarded more than once
- MISRA C++ 2023 Rule 28.6.1 - The argument to
std::move
shall be a non-const lvalue
External coding guidelines