[previous] MISRA C:2012  Rule-13.2:  (Required) [next] The value of an expression and its persistent side-effects shall be the same under all permitted evaluation orders

Amplification:

Between any two adjacent sequence points or within any full expression:

  1. No object shall be modified more than once;
  2. No object shall be both modified and read unless any such read of the object's value contributes towards computing the value to be stored into the object;
  3. There shall be no more than one modification access with volatile-qualified type;
  4. There shall be no more than one read access with volatile-qualified type.

Note: An object might be accessed indirectly, by means of a pointer or a called function, as well as being accessed directly by the expression.

Note: This Amplification is intentionally stricter than the headline of the rule. As a result, expressions such as:

x = x = 0;
are not permitted by this rule even though the value and the persistent side-effects, provided that x is not volatile, are independent of the order of evaluation or side-effects.

Sequence points are summarized in Annex C of both the C90 and C99 standards. The sequence points in C90 are a subset of those in C99.

Full expressions are defined in Section 6.6 of the C90 standard and Section 6.8 of the C99 standard.

Example Code:


#pragma PRQA_MESSAGES_OFF 2982,2983,2984,2996

#include "misra.h"
#include "m3cmex.h"


static int16_t rule_1302a( int16_t *p );
static int16_t rule_1302b( int16_t *p );
static int16_t rule_1302c( const int16_t *p );


#define MAX 15

extern int16_t rule_1302( void )
{
   const int16_t buf[20] = {0};
   int16_t       x = 5;
   int16_t       y = 10;

   /***********************************************************************/
   /* 0400 '%s' is modified more than once between sequence points        */
   /*      - evaluation order unspecified.                                  */
   /***********************************************************************/

   x = y + ( x++ );                                                                     /* 0400 3440 */

   /* The order of the increment and assignment ARE NOT specified */
   x = ( x > MAX ) ? ( ++x ) : 0;                                                       /* 0400 3440 */

   /* The order of the increment and assignment ARE NOT specified */
   x = ( y > MAX ) ? ( ++x ) : 0;                                                       /* 0400 3440 */


   /***********************************************************************/
   /* 0401 '%s' may be modified more than once between sequence points    */
   /*      - evaluation order unspecified.                                  */
   /*                                                                     */
   /* This message is generated in situations where it is not certain     */
   /* that an object is modified more than once but the passing of a      */
   /* pointer to that object suggests it may be                           */
   /***********************************************************************/


   y = rule_1302a( &x ) + ( x++ );                                                      /* 0401 3440 */
   y = rule_1302a( &x ) + rule_1302b( &x );                                             /* 0401      */

   /* In the following statement, there is a sequence point after the
      evaluation of the first operand of the ternary operator, so "x"
      is known to be incremented before the assignment occurs. The
      code may be silly, but it is not undefined */

   x = ( ( ++x ) > MAX ) ? 0 : 1;                                                       /*      3440 */


   /* In these statements, any modification to the value of x by the
      function rule_1302a is known to occur before the assignment and
      therefore, although "x" may be modified more than once, the order
      of evaluation is not undefined */

   x = rule_1302a( &x );                                                                /*           */

   x = ( y > MAX ) ? rule_1302a( &x ) : 0;                                              /*           */

   /* The prototype of rule_1302c declares a "pointer to const int16_t"
      parameter and so there is no possibility of x being modified more
      than once */

   y = rule_1302c( &x ) + ( x++ );                                                      /*      3440 */



   /***********************************************************************/
   /* 0402 '%s' is modified and accessed between sequence points          */
   /*      - evaluation order unspecified.                                */
   /***********************************************************************/

   y = ( x + 6 ) / ( x++ );                                                             /* 0402 3440 */

   y = buf[ x ] + ( x++ );                                                              /* 0402 3440 */

   y = ( x > MAX ) ? ( x++ ) : 0;                                                       /*      3440 */


   /***********************************************************************/
   /* 0403 '%s' may be modified and accessed between sequence points      */
   /*      - evaluation order unspecified.                                */
   /***********************************************************************/

   y = rule_1302a( &x ) + x;                                                            /* 0403       */
   y = buf[ x ] + rule_1302a( &x );                                                     /* 0403       */

   /* The prototype of rule_1302c declares a "pointer to const int16_t"
      parameter and so there is no possibility of x being modified */

   y = rule_1302c( &x ) + x;                                                            /*            */
   y = buf[ x ] + rule_1302c( &x );                                                     /*            */

   return 1;
}

static int16_t rule_1302a( int16_t *p )
{
   *p = 1;

   return 1;
}

static int16_t rule_1302b( int16_t *p )
{
   *p = 2;

   return 1;
}

static int16_t rule_1302c( const int16_t *p )
{
   int16_t r;

   r = *p * 2;

   return r;
}


QAC messages that encompass this guideline:

0400 [U] '%s' is modified more than once between sequence points - evaluation order unspecified.
0401 [U] '%s' may be modified more than once between sequence points - evaluation order unspecified.
0402 [U] '%s' is modified and accessed between sequence points - evaluation order unspecified.
0403 [U] '%s' may be modified and accessed between sequence points - evaluation order unspecified.


Related rules:

Rule-1.3 There shall be no occurrence of undefined or critical unspecified behaviour



(c) The Motor Industry Research Association, 2012
QA C Source Code Analyser 8.1.2
MISRA C:2012 Compliance Module 1.0
© 2013 Programming Research
www.programmingresearch.com
Personality Groups | Glossary | Message Index | MISRA C:2012 Rule Index Contents