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.18.1 - An object or subobject must not be copied to an overlapping object
[expr.ass] Undefined 8
Category: Mandatory
Analysis: Undecidable,System
Amplification
This rule applies when:
- A member of a union is copied to a different member of the same union; or
- A slice of an array is copied to an overlapping slice of the same array using
memcpy.
Rationale
Copying between members of the same union object may result in undefined behaviour.
If part of an array is to be copied to another part of the same array (e.g. when moving elements 1 to 10 to elements 0 to 9), then
std::memcpy may overwrite an element before it has been copied, as there is no guarantee of the order in which they are copied. By
contrast, std::memmove is guaranteed to handle the overlap appropriately.
Example
The use of unions in the following example is a violation of M23_158: MISRA C++ 2023 Rule 12.3.1.
void f1( void )
{
union
{
int16_t i;
int32_t j;
} a = { 0 };
a.i = a.i; // Rule does not apply - same member
a.j = a.i; // Non-compliant
}
void f2( std::array< int16_t, 20 > & a )
{
memcpy ( &a[ 0 ], &a[ 1 ], 10u * sizeof ( a[ 0 ] ) ); // Non-compliant
memmove( &a[ 0 ], &a[ 1 ], 10u * sizeof ( a[ 0 ] ) ); // Rule does not apply
memcpy ( &a[ 1 ], &a[ 0 ], 10u * sizeof ( a[ 0 ] ) ); // Non-compliant
memmove( &a[ 1 ], &a[ 0 ], 10u * sizeof ( a[ 0 ] ) ); // Rule does not apply
memcpy ( &a[ 0 ], &a[ 5 ], 5u * sizeof ( a[ 0 ] ) ); // Compliant - no overlap
}
Copyright The MISRA Consortium Limited © 2023