[previous] MISRA-C:2004  Rule  12.2:  (Required) [next] The value of an expression shall be the same under any order of evaluation that the standard permits.
Apart from a few operators (notably the function call operator (), &&, ||, ?: and , (comma)) the order in which sub-expressions are evaluated is unspecified and can vary. This means that no reliance can be placed on the order of evaluation of sub-expressions, and in particular no reliance can be placed on the order in which side effects occur. Those points in the evaluation of an expression at which all previous side effects can be guaranteed to have taken place are called 'sequence points'. Sequence points and side effects are described in sections 5.1.2.3, 6.3 and 6.6 of ISO/IEC 9899:1990 [2].

Note that the order of evaluation problem is not solved by the use of parentheses, as this is not a precedence issue.

Example Code:


/* PRQA S 2982-2984,2996,3447 ++ */

#include "misra.h"
#include "m2cmex.h"


static S16 test_1202a( S16 *p );
static S16 test_1202b( S16 *p );
static S16 test_1202c( const S16 *p );


#define MAX 15

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

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

   x = y + ( x++ );                              /* MISRA Violation  */


   /***********************************************************************/
   /* 0401 '%s' may be modified more than once between sequence points    */
   /*      - evaluation order undefined.                                  */
   /***********************************************************************/

   /* 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 = test_1202a( &x ) + ( x++ );               /* MISRA Violation  */
   y = test_1202a( &x ) + test_1202b( &x );      /* MISRA Violation  */

   /* In this case the order of the increment and assignment ARE NOT defined */

   x = ( x > MAX ) ? ( ++x ) : 0;                /* MISRA Violation  */

   /* In this case the order of the increment and assignment ARE NOT defined */

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

   /* 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;                /* OK               */


   /* In these statements, any modification to the value of x by the function
      test_1202a 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 = test_1202a( &x );                         /* OK               */

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

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

   y = test_1202c( &x ) + ( x++ );               /* OK               */



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

   y = ( x + 6 ) / ( x++ );                      /* MISRA Violation  */

   y = buf[ x ] + ( x++ );                       /* MISRA Violation  */

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


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

   y = test_1202a( &x ) + x;                     /* MISRA Violation   */
   y = buf[ x ] + test_1202a( &x );              /* MISRA Violation   */

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

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

   return 1;
}

static S16 test_1202a( S16 *p )
{
   *p = 1;

   return 1;
}

static S16 test_1202b( S16 *p )
{
   *p = 2;

   return 1;
}

static S16 test_1202c( const S16 *p )
{
   S16 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.2 No reliance shall be placed on undefined or unspecified behaviour.



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