简体   繁体   中英

MISRA 2012 Rule 14.2

I have a question related to MISRA 2012 Rule 14.2 "A for loop shall be well-formed"

Conside below sample code :

int foo (int *ptr)
{
    (*ptr)--;
     return *ptr;
}

void main()
{
    int a =20;
    int i;
    for (i=0; i< foo(&a) ; i++)
    {
         /*
         <loop body>
         */       
    }
}

Here for line for (i=0; i< foo(&a) ; i++) I am getting a MISRA violation, 14.2. The question is when we modify the variable (a) present in the loop condition (i< foo(&a)), in a function like shown. is it valid violation ?

Its just a sample case, for 14.2, Please do not focus on the loop being infinite in the above sample code.


14.2 Rule : Second clause which
- Shall be an expression that has no persistent side effects, and
- Shall use the loop counter and optionally loop control flags, and
- Shall not use any other object that is modified in the for loop body.

Example :-

 bool_t flag = false;
    for ( int16_t i = 0; ( i < 5 ) && !flag; i++ )
    {
    if ( C )
    {
    flag = true; /* Compliant - allows early termination
    * of loop */
    }
    i = i + 3; /* Non-compliant - altering the loop
    * counter */
    }

Your example code violates the quoted rule (first bullet) because
it does have side effects (or the compiler cannot really tell, because of calling a function with a prototype which would allow such side effects - and happens to have at least one).

Your example might violate the quoted rule (third bullet) if the (side-) effects of the loop continuation condition ( i< foo(&a) ) are counted (by your specific MISRA analyser) as part of "the loop body". (I would not, but your tool might.)

So your shown code violates the rule between one and two times.

The rationale for Rule 14.2 shows that this Rule is intended to restrict for loops, stopping "clever" uses, and thus make code easier to review and analyse...

I have a simple maxim:

  • If you have a pre-determinable number of iterations, use a for loop
  • If you don't have a pre-determinable number of iterations, use a while ... do loop

Assuming foo(&a) is does not return a constant, you would be better off using a while ... do loop:

int a = 20;
int i = 0;

while ( i < foo(&a) )
{
  // Loop body
  ...
  ++i;
}

Note: See profile for disclaimer.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM