This rule is part of MISRA C++:2023.
Usage of this content is governed by Sonar’s terms and conditions. Redistribution is
prohibited.
Rule 4.6.1 - Operations on a memory location shall be sequenced appropriately
[intro.execution] Undefined 17
Category: Required
Analysis: Undecidable,System
Amplification
A side effect on a memory location shall not be unsequenced or indeterminately sequenced with respect to any other side effect on
the same memory location, or any value computation using the value of any object in the same memory location.
For the purposes of this rule, all volatile accesses are considered to access a single, unique memory location.
Rationale
Unsequenced accesses to a memory location when one of the accesses has side effects results in undefined behaviour.
Additionally, indeterminately sequenced accesses could result in an expression yielding a different value for differing program states.
This rule ensures that a program’s behaviour is independent of the evaluation order (such as the evaluation of function arguments) chosen by the
compiler.
An access to a volatile v1 may have an effect on another, seemingly unrelated, volatile v2. For this reason, this rule
considers all volatile accesses as if they were to a single, unique memory location.
Note: C++17 changed the evaluation order of several expressions from indeterminately sequenced to sequenced
before, which means that code that is compliant with this rule may not work correctly with earlier versions of C++.
Example
char f( char & c, char a )
{
c = a;
return c;
}
void h( char a, char b );
char a;
h( f( a, 'a' ), f( a, 'b' ) ); // Non-compliant - value of a could be 'a' or 'b'
In the following example, i is read twice and modified twice. However, since C++17, the evaluation of the right-hand side of an
assignment is sequenced before the evaluation of the left-hand side (see [expr.ass]), so all accesses to i occur in a defined
order:
a[ i++ ] = b[ i++ ]; // Compliant in C++17
Even though there is no undefined behaviour in the following examples, they are non-compliant as the uses of i are
indeterminately sequenced with respect to their increments:
x = b[ i ] + i++; // Non-compliant
x = func( i++, i ); // Non-compliant
In the following example, all accesses to volatile variables are considered to have side effects on the same memory location:
extern volatile uint16_t v1;
extern volatile uint16_t v2;
uint16_t t = v1 + v2; // Non-compliant - indeterminately sequenced
v1 = v1 & 0x80u; // Compliant
Copyright The MISRA Consortium Limited © 2023