This is a draft version of a MISRA C++ 202x rule proposed for public review.
MISRA Rule 28.6.4
Category: Required
Analysis Type: Decidable,Single Translation Unit
Amplification
For the purposes of this rule, a cast to void
is not considered to be a use [1].
This rule applies to member and non-member forms of empty
within the C++ Standard Library.
This rule does not apply to the std::remove( const char * )
overload defined in <cstdio>
.
Rationale
The mutating algorithms std::remove
, std::remove_if
and overloads of std::unique
operate by swapping or
moving elements of the range they are operating over. On completion, they return an iterator to one past the last valid element. In the majority of
cases, the correct behaviour is to use this result as the first operand in a call to std::erase
.
Ignoring the result of empty
may indicate that a developer expects the call to purge the contents of the container, while it actually
reports if it contains data.
Example
void f1()
{
std::vector< int32_t > v1 = { 0, 0, 1, 1, 2, 2, 3, 3 };
std::vector< int32_t > v2 = v1;
std::unique( v1.begin(), v1.end() ); // Non-compliant
// v1 now holds { 0, 1, 2, 3, ?, ?, ?, ? }
// where ? represents an unknown value
v2.erase( std::unique( v2.begin(), v2.end() ),
v2.end() ); // Compliant
// Contents of v2 is now { 0, 1, 2, 3 }
}
void f2( std::vector< int32_t > & v3 )
{
empty( v3 ); // Non-compliant - result not used
v3.empty(); // Non-compliant - result not used
if ( !empty( v3 ) ) // Compliant
{
v3.clear(); // Purges the vector
}
}
Glossary
[1] Use / used / using
An object is used if:
- It is the subject of a cast; or
- It is explicitly initialized at declaration time; or
- It is an operand in an expression; or
- It is referenced.
A function is used as defined in M23_331: MISRA C++ 2023 Rule 0.2.4.
A type is used as defined in MISRA C++ 2023 Rule 0.2.3 (Types with limited visibility should be used at least
once).
Copyright The MISRA Consortium Limited © 2023