Main Content

MISRA C:2012 Rule 14.1

A loop counter shall not have essentially floating type

Description

Rule Definition

A loop counter shall not have essentially floating type.

Rationale

When using a floating-point loop counter, accumulation of rounding errors can cause the actual number of iterations to be different than the number of iterations you expect. This rounding error can happen when a loop step that is not a power of the floating-point radix is rounded to a value that can be represented by a float.

Even if a loop with a floating-point loop counter appears to behave correctly on one implementation, it can give a different number of iterations on another implementation.

Polyspace Implementation

Polyspace® reports a violation of this rule if the essential type of a loop counter variable is float.

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

int main(void){
    unsigned int counter = 0u;
    int result = 0;
    float foo;

    // Float loop counters
    for(float foo = 0.0f; foo < 1.0f; foo +=0.001f){/* Non-compliant*/
        ++counter;
    }

    float fff = 0.0f; 
    for(fff = 0.0f; fff <12.0f; fff += 1.0f){/* Non-compliant*/
        result++;
    }

    // Integer loop count
    for(unsigned int count = 0u; count < 1000u; ++count){/* Compliant */
        foo = (float) count * 0.001f;
    }
}

In this example, the three for loops show three different loop counters. The first and second for loops use float variables as loop counters, and therefore are not compliant. The third loop uses the integer count as the loop counter. Even though count is used as a float inside the loop, the variable remains an integer when acting as the loop index. Therefore, this for loop is compliant.

This example shows two while loops. The loops use floating-point variables in the while-loop conditions:

  • The first while loop uses the floating-point variable foo in the loop condition and inside the loop. When foo is updated in the loop, floating-point rounding errors can cause unexpected behavior. Polyspace reports a violation.

  • The second while loop uses the floating point array buffer and two integers iter1 and inter2 in the loop condition. Polyspace identifies iter1 and iter2 as the loop counters. Because these loop counters are not floating point variables, Polyspace does not report a violation.

int main(void){
    unsigned int iter1 =0;
    int iter2;
    float foo;
    double buffer[2];
    double tmp;

    foo = 0.0f;
    while (foo < 1.0f){/* Non-compliant - foo used as a loop counter */
        foo += 0.001f;  
    }
       
	//...
    while((iter1+1 < 2)&& (buffer[iter1]<buffer[iter2])){ //Compliant - loop counter is integer
		// swap buffer[iter1] and buffer[iter2]
        tmp = buffer[iter2];
        buffer[iter2] = buffer[iter1];
        buffer[iter1] = tmp;
        iter2 = iter1;
        iter1++;
    }
						
    return 1; 
}

Check Information

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

Version History

expand all