Main Content

AUTOSAR C++14 Rule A8-4-7

"in" parameters for "cheap to copy" types shall be passed by value

Description

Rule Definition

"in" parameters for "cheap to copy" types shall be passed by value.

Rationale

You use an "in" parameter when you intend to only read that parameter within a function. If the parameter is cheap to copy, pass the parameter by value to:

  • Make it clear that you do not plan on modifying the parameter.

  • Avoid the additional indirection that is required to access the parameter from the function when you pass the parameter by reference.

A parameter is cheap to copy when both these conditions are true:

  • The parameter has a size less than or equal to two words. For instance, for a parameter foo, sizeof(foo) <= 2 * sizeof(int).

  • The parameter is trivially copyable type. See is_trivially_copyable.

Polyspace Implementation

  • Polyspace® flags:

    • const parameters that are passed by reference if the parameters are cheap to copy (sizeof <= 2 * sizeof(int) and trivially copyable).

    • const parameters that are passed by value if the parameters are not cheap to copy. For instance, in this code snippet, both parameters str (expensive to copy) and b (non-trivially copyable) are noncompliant.

      void func1(const std::string str);
      struct B {
          B(B const&) {}
      };
      void func2(const B b);

  • Polyspace does not flag :

    • Non-const parameters that are passed by reference if those parameters are not cheap to copy and are not modified inside the function. Polyspace considers these parameters as "in" parameters.

    • "in" parameters that are passed by reference if those parameters are move-only types. For instance, int f(const std::unique_ptr<int>& p);.

    • const parameters that are passed by reference in copy constructors. For instance, no defect is raised on point in this code snippet.

      class coord
      {
      public:
          coord(int x, int y) {p_x = x; p_y = y;}
          coord(const coord& point) { p_x = obj.p_x; p_y = obj.p_y;}
          //...
      private:
          int p_x, p_y;
      
      
      };
      coord point{1, 1};
      void func(const coord& point);

Troubleshooting

If you expect a rule violation but Polyspace does not report it, see Diagnose Why Coding Standard Violations Do Not Appear as Expected.

Examples

expand all

#include <memory>
#include <string>
#include <cstdint>

int func(const std::unique_ptr<int>& ptr) // Compliant
{
    *ptr = *ptr + 1;
    return *ptr;
}
union Small {
    uint8_t var1 ;
    uint8_t var2;
} ;

struct Large {
    std::uint32_t v1;
    std::uint32_t v2;
    std::uint32_t v3;
    std::uint32_t v4;
};

void func2(Small& arg) // Noncompliant
{
//...
}  

void func3(Large val,   // Noncompliant
           std::string& str) // Compliant
{
//...
} 

In this example, Polyspace flags "in" parameters:

  • arg, because it is passed by reference and its type is trivially copyable. This parameter can be passed by value instead.

  • val, because it is passed by value and it is expensive to copy. Passing this parameter by reference avoids making expensive copies for each call to func3().

These passed by reference "in" parameters are compliant:

  • Parameter ptr because it is a move-only type.

  • Parameter str because it is expensive to copy. This parameter is non-const but it is not modified inside func3().

Check Information

Group: Declarators
Category: Required, Automated

Version History

Introduced in R2019a

expand all