Uploaded image for project: 'Rules Repository'
  1. Rules Repository
  2. RSPEC-6234

"auto" should be used to store a result of functions that conventionally return an iterator

    XMLWordPrintable

    Details

    • Type: Code Smell Detection
    • Status: Active
    • Resolution: Unresolved
    • Labels:
    • Default Severity:
      Minor
    • Impact:
      Low
    • Likelihood:
      Low
    • Default Quality Profiles:
      Sonar way
    • Targeted languages:
      C++
    • Remediation Function:
      Constant/Issue
    • Constant Cost:
      2min
    • Analysis Level:
      Syntactic Analysis
    • Analysis Scope:
      Main Sources, Test Sources

      Description

      auto is a type placeholder that may be used in variable declarations to instruct the compiler to infer the type from the initializer.

      The use of auto reduces unnecessary boilerplate in the situation when the type of the variable is apparent from the context. However, outside of some obvious situations (e.g. when type is spelled in the initializer), the judgment is hard to make. Usually, it is trying to balance between the verbosity of type and the readability from the contributor's perspective.

      Arguably, in the case of the variables initialized from a function that conventionally returns an iterator (e.g. begin, end, std::find), it is clear that the type of the variable is some iterator. Spelling the exact type of the iterator in such a situation does not improve the clarity of the code, especially considering their usual verbosity.

      This rule raises an issue on the declaration of a variable with an explicit iterator type. and that is initialized from call to a function that conventionally returns an iterator:

      • begin and end functions and their const and reverse variants
      • standard algorithms that return iterators

      Noncompliant Code Example

      #include <vector>
      #include <map>
      
      std::vector<int>::iterator someFunction(std::vector<int>& v);
      
      void f() {
        std::vector<int> v;
        const std::vector<int>& cv = v;
        std::vector<int>::iterator it1 = v.begin(); // Noncomplaint
        std::vector<int>::const_iterator it2 = v.begin(); // Complaint
        std::vector<int>::const_iterator it3 = v.cbegin(); // Noncomplaint   
        std::vector<int>::const_iterator it4 = cv.cbegin(); // Noncomplaint   
        std::vector<int>::const_iterator it5 = std::begin(cv); // Noncomplaint
       
        std::vector<int>::iterator it6 = std::find(v.begin(), v.end(), 10);  // Noncomplaint
        std::vector<int>::iterator it7 = someFunction(10);  // Complaint
      
         std::map<int, string> m;
         if (std::map<int, string>::iterator it = m.find(20); it != m.end()) { // Noncomplaint
            // do something 
        }
      }
      

      Compliant Solution

      /* ... */
      
      void f() {
        std::vector<int> v;
        const std::vector<int>& cv = v;
        auto it1 = v.begin(); 
        std::vector<int>::const_iterator it2 = v.begin();
        auto it3 = v.cbegin();
        auto it4 = cv.cbegin();
        auto it5 = std::begin(cv);
       
        auto it6 = std::find(v.begin(), v.end(), 10);
        std::vector<int>::iterator it7 = someFunction(10);
      
         std::map<int, string> m;
         if (auto it = m.find(20); it != m.end()) {
            // do something 
        }
      }
      

      See

      • S5827 - use auto to avoid repetition of types

        Attachments

          Issue Links

            Activity

              People

              Assignee:
              Unassigned Unassigned
              Reporter:
              tomasz.kaminski Tomasz Kamiński
              Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

                Dates

                Created:
                Updated: