Main Content

Inefficient use of for loop

Range-based for loop can perform equivalent iteration more efficiently

Since R2022a

Description

This defect occurs when you use for loops that loop through all elements of a container or a C-style array and both of these conditions are true:

  • The for loop has only one loop counter variable. For instance, Polyspace® does not flag this for loop:

    for(int i=0, j=0; i < 10; ++i, ++j){
    //...
    }

  • The for loop uses the loop counter variable to access only the elements of the container or the C-style array. For instance, in this code snippet, Polyspace flags the first loop but not the second one.

    #include <iostream>
    
    int myArray[10]
    
    void cArray()
    {
        //First loop: Loop counter used only to access elements of myArray
        for (int i = 0; i < 10; ++i) {
            myArray[i] = 0;
        }
        
        //Second loop: Loop counter assigned to elements of myArray
        for (int i = 0; i < 10; ++i) {
            myArray[i] = i;
        }
    
    
    }

Polyspace does not raise an Inefficient use of for loop defect in these scenarios:

  • You iterate through a user-defined container. For instance, this for loop is compliant.

    template<typename T>
    class customContainer {
      typedef T* iterator;
      public:
        iterator begin();
        iterator end();
    };
    
    void func() {
      customContainer<int> myContainer;
    
      for(auto it = myContainer.begin(); it != myContainer.end(); it++) { 
        std::cout << *it;
      }
    }
    Polyspace raises a defect only for C-style arrays and Standard Template Library containers.

  • You use reverse iterators to loop through the elements of the C-style array or container. For instance, in this code snippet, there is no defect because you cannot use a range-based for loop to perform an equivalent operation.

    #include <iostream>
    #include <vector>
    #include <cstdint>
    
    std::vector<std::uint32_t> myVector(10);
    
    void myContainer()
    {
        //loop uses reverse iteration
        for (auto it = myVector.rbegin(); it != myVector.rend(); ++it) {
    
            std::cout << *it;
        }
    }
    

  • If you loop through arrays:

    • You loop through the elements of multiple arrays or you loop through the elements of a multidimensional array.

    • The array size is unknown.

    For instance, Polyspace does not flag these for loops:

    int myArray[10];
    int myOtherArray[10];
    int multiArray[10][10];
    
    void cArray()
    {
        //loop through multiple array
        for (int i = 0; i < 10; ++i) {
            myArray[i] = 0;
            myOtherArray[i] = 0;
        }
        //loop through 2-dimensional array
        for (int i = 0; i < 10; ++i) {
            multiArray[i][i] = 0;
        }
    
    }
    
    void unknownSize(int someArray[])
    {
        //loop through array of unknown size
        for (int i = 0; i < 10; ++i) {
            someArray[i] = 0;
        }
    }

Risk

If you loop through all the elements of a container or a C-style array and you use the loop counter variable to access only the value of the elements, a for loop is slower, less readable, and more difficult to maintain than an equivalent range-based for loop.

Fix

Replace the for loop with a range-based for loop, which makes your code run more efficiently, more readable, and easier to maintain.

Examples

expand all

#include <iostream>
#include <vector>
#include <cstdint>

std::vector<std::uint32_t> myVector(10);

void myContainer()
{
    for (auto it = myVector.begin(); it != myVector.end(); ++it) {
        std::cout << *it;
    }
}

In this example, Polyspace flags the for loop, which iterates through all the elements of vector myVector and uses the loop counter it to only print the value of each element. To run this example, specify C++ version as cpp11.

Correction — Use a Range-Based for Loop Instead

One possible correction is to use a range-based for loop to perform an equivalent operation. The range-based for loop uses less code and makes your code run more efficiently, more readable, and easier to maintain

#include <iostream>
#include <vector>
#include <cstdint>

std::vector<std::uint32_t> myVector(10);

void myContainer()
{
    for (auto it : myVector) {
        std::cout << it;
    }
}

Result Information

Group: Performance
Language: C++
Default: Off
Command-Line Syntax: PREFER_RANGE_BASED_FOR_LOOPS
Impact: Low

Version History

Introduced in R2022a