Main Content

MISRA C:2012 Rule 14.2

A for loop shall be well-formed

Description

Rule Definition

A for loop shall be well-formed.

Rationale

The for loop provides a flexible looping facility. You can perform other operations besides the loop counter initialization, termination, and increment in the control statement, and increment the loop counter anywhere inside the loop body. However, using a restricted loop format makes your code easier to review and to analyze.

Polyspace Implementation

A for loop consists of a control statement with three clauses and a loop body. The checker raises a violation if:

  • The first clause does not contain an initialization (except for when the clause is empty). The checker considers the last assigned variable of the first for-loop clause as the loop counter. If the first clause is empty, the checker considers the variable incremented or decremented in the third clause as the loop counter.

  • The second clause does not contain a comparison operation involving the loop counter.

  • The third clause contains an operation other than incrementing or decrementing the loop counter (separated by a comma from the increment or decrement).

  • The loop counter has a data type that is not an integer or a pointer type.

  • The loop counter is incremented inside the loop body.

Polyspace® does not raise a violation when the second clause includes a binary operation that involves the loop counter.

Troubleshooting

If you expect a rule violation but do not see it, refer to Diagnose Why Coding Standard Violations Do Not Appear as Expected.

Examples

expand all

void foo(void){

    for(short index=0; index < 5; index++){  /* Non-compliant */
        index = index + 3;       /* Altering the loop counter */
    }
}

In this example, the loop counter index changes inside the for loop. It is hard to determine when the loop terminates.

Correction — Use Another Variable to Terminate Early

One possible correction is to use an extra flag to terminate the loop early.

In this correction, the second clause of the for loop depends on the counter value, index < 5, and upon an additional flag, !flag. With the additional flag, the for loop definition and counter remain readable, and you can escape the loop early.

#define FALSE 0
#define TRUE  1

void foo(void){

    int flag = FALSE;

    for(short index=0; (index < 5) && !flag; index++){ /* Compliant */
        if((index % 4) == 0){
            flag = TRUE;        /* allows early termination of loop */
        }
    }
}
void foo(void){
    for(short index = 0; ; index++) {}   /* Non-compliant */

    for(short index = 0; index < 10;) {} /* Non-compliant */

    short index;
    for(; index < 10;) {}     /* Non-compliant */

    for(; index < 10; index++) {} /* Compliant */

    for(;;){}  
          /* Compliant - Exception all three clauses can be empty */
}

This example shows for loops definitions with a variety of missing clauses. To be compliant, initialize the first clause variable before the for loop (line 9). However, you cannot have a for loop without the second or third clause.

The one exception is a for loop with all three clauses empty, so as to allow for infinite loops.

Check Information

Group: Control Statement Expressions
Category: Required
AGC Category: Readability

Version History

expand all