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

"std::string_view" and "std::span" parameters should be directly constructed from sequences

    XMLWordPrintable

    Details

    • Default Severity:
      Major
    • Impact:
      Low
    • Likelihood:
      High
    • Default Quality Profiles:
      Sonar way
    • Targeted languages:
      C++
    • Remediation Function:
      Constant/Issue
    • Constant Cost:
      2min
    • Analysis Level:
      Semantic Analysis
    • Analysis Scope:
      Main Sources, Test Sources

      Description

      C++20 introduced std::span and std::string_view as thin generic wrappers for a contiguous sequence of elements. These wrappers can be used to unify the interface of functions that were previously accepting references to specific container types: const std::string&, const std::vector<int>&...

      One of the benefits of such modernization is that it eliminates the need to explicitly create a temporary container. This happens in situations where part of the sequence is passed as an argument: substr is called on std::string. It can also happen when the type of the container elements needs to be adjusted: converting std::vector<T*> to std::vector<const&>. When changing the type of a function parameter to std::string_view or std::span the modification of the function call site to remove the no longer needed temporary might be missed and the code will still compile. This rule will help eliminate these temporaries.

      This rule raises an issue when an unnecessary temporary is passed as an argument to a parameter of std::string_view or std::span type.

      Noncompliant code example

      void process(std::string_view sv);
      bool oddAre0(const std::span<int const*>& nums);
      std::vector<int*> getNums();
      
      void caller(std::string const& s) {
        process(s.substr(10)); // Noncompliant
        process(std::string(s.data(), 20)); // Noncompliant
      
        std::vector<int*> nums = getNums();
        if (oddAre0(std::vector<int const*>{nums.begin(), nums.end()})) { // Noncompliant: This copy is verbose and slow
          // ...
        }
      
      }
      

      Compliant solution

      void process(std::string_view sv);
      bool oddAre0(const std::span<int const*>& nums);
      std::vector<int*> getNums();
      
      void caller() {
        process(std::string_view(s).substr(10));
        process(std::string_view(s.data(), 20));
        std::vector<int*> nums = getNums();
        if (oddAre0(nums)) {
          // ...
        }
      }
      

      See

      • RSPEC-6009 - using std::string_view as a parameter type
      • RSPEC-6188 - using std::span as a parameter type

        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: