Main Content

AUTOSAR C++14 Rule A13-5-5

Comparison operators shall be non-member functions with identical parameter types and noexcept

Since R2020b

Description

Rule Definition

Comparison operators shall be non-member functions with identical parameter types and noexcept.

Rationale

Comparison operators must not compare objects that are of different types. If you pass objects of different types as arguments to a comparison operator, the operator must be able to convert one argument to the data type of the other.

Member functions have the inherent limitation that the implicit object parameter (the one referred to by the this pointer) cannot be converted to another data type. To support data type conversions when required, define comparison operators as non-member functions.

Comparison expressions are fundamental operations and must be noexcept. The comparison operators covered by this rule are:

  • ==

  • !=

  • <

  • <=

  • >

  • >=

Note

Declare comparison operators as friend to enable them to access internal data similar to a member function. This practice is allowed by the exception in rule A11-3-1.

Polyspace Implementation

The checker flags comparison operators that are defined as member functions. The checker also flags non-member comparison operators that:

  • Compare nonidentical parameter types, such as a class type and int.

  • Are not declared with the noexcept specifier.

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

The declaration of nonComp::operator::== is noncompliant because the comparison operator is declared as a member function.

#include <cstdint>

class nonComp
{
  public:
      explicit nonComp(std::uint32_t d): m_d(d)
      {}
      bool operator ==(const nonComp& rhs) noexcept  //Non-compliant; member function 
      { 
          return m_d == rhs.m_d;
      }
  
  private:
      std::uint32_t m_d;
};


class Compliant
{
  public:
      explicit Compliant(std::uint32_t d): m_d(d)
      {}
      friend bool operator ==(Compliant const& lhs, Compliant const& rhs) noexcept
      {
          return lhs.m_d == rhs.m_d;
      }
  private:
      std::uint32_t m_d;
};
// Compliant; non-member, identical parameter types, noexcept

The class Compliant declares operator::== as a friend, so this comparison operator is compliant.

The first declaration of operator::== compares two different data types, because of which this comparison operator is noncompliant.

#include <cstdint>

class nonComp
{
    using Self = nonComp;
};

class MemberFunc
{
    using Self = MemberFunc;
};

bool operator ==(const nonComp& lhs, //noncompliant; comparison operator for different data types.
                 const MemberFunc& rhs) noexcept
{
    return true;
}


bool operator ==(const nonComp& lhs, const nonComp& rhs) noexcept
{
    return true;
} //compliant; because it compares the same data types.

The second declaration of operator::== compares the same data types, so this comparison operator is compliant.

nonComp::operator::== is not declared as a noexcept, so this comparison operator is noncompliant.

#include<cstdint>
class nonComp
{
  public:
    explicit nonComp(std::uint32_t d): m_d(d)
    {}
    friend bool operator ==(nonComp const& lhs, //Noncompliant; member function isn't noexcept 
                            nonComp const& rhs)
    {
        return lhs.m_d == rhs.m_d;
    }

  private:
    std::uint32_t m_d;
};


class Compliant
{
  public:
    explicit Compliant(std::uint32_t d): m_d(d)
    {}
    friend bool operator ==(Compliant const& lhs, Compliant const& rhs) noexcept
    {
        return lhs.m_d == rhs.m_d;
    }

  private:
    std::uint32_t m_d;
};
// Compliant; non-member, identical parameter types, noexcept

Compliant::operator::== is declared as a noexcept, so this comparison operator is compliant.

Check Information

Group: Overloading
Category: Required, Automated

Version History

Introduced in R2020b