Main Content

AUTOSAR C++14 Rule A9-3-1

Member functions shall not return non-constant "raw" pointers or references to private or protected data owned by the class

Description

Rule Definition

Member functions shall not return non-constant "raw" pointers or references to private or protected data owned by the class.

Rationale

Returning a nonconstant pointer or reference to private or protected class-owned data enables clients to externally access and modify the state of the object without an interface. Such access without an explicit interface might bypass the private/protected data access hierarchy of the class, which might result in unexpected behavior and lead to bugs.

This rule applies to data that is owned by the class. Nonconstant handles to objects that are shared between different classes might be returned. Classes that mimic smart pointers and containers do not violate this rule.

Polyspace Implementation

The checker flags a rule violation only if a member function returns a non-const pointer or reference to a nonstatic data member. The rule does not apply to static data members.

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 <cstdint>
#include <memory>
#include <utility>

class A
{
  public:
    explicit A(std::int32_t number) : x(number) {}
    std::int32_t&
    GetX() noexcept // Noncompliant
    {
      return x;
    }
 
  private:
    std::int32_t x;
};

void Fn1() noexcept
{
  A a{10};
  std::int32_t& number = a.GetX();
  number = 15; // External modification of private class data
}

In this example, the class A member function GetX() returns a non-constant raw pointer to x, which is private data owned by class A. Polyspace flags this implementation as noncompliant. Fn1() demonstrates the issues of a.GetX() returning a non-constant raw pointer to private class data, which is then stored and modified by number. The class has no control over changes to its own private data member, which might lead to unexpected behavior.

#include <cstdint>
#include <memory>
#include <utility>
class B
{
  public:
    explicit B(std::shared_ptr<std::int32_t> ptr) : sharedptr(std::move(ptr)) {}
    std::shared_ptr<std::int32_t> GetSharedPtr() const noexcept // Compliant 
    {
      return sharedptr;
    }
 
  private:
    std::shared_ptr<std::int32_t> sharedptr;
};

void Fn2() noexcept
{
  std::shared_ptr<std::int32_t> ptr = std::make_shared<std::int32_t>(10);
  B b1{ptr};
  B b2{ptr};
  *ptr = 50; // External modification of ptr which shared between b1 and b2
  // instances
  auto shared = b1.GetSharedPtr();
 
  *shared = 100;   // External modification of ptr which shared between b1 and
  // b2 instances
}

In this example, the class B function GetSharedPtr() returns a smart pointer variable that is shared between the instances b1 and b2. Polyspace does not flag this implementation as noncompliant.

#include <cstdint>
#include <memory>
#include <utility>
class C
{
  public:
    explicit C(std::int32_t number)
      : ownedptr{std::make_unique<std::int32_t>(number)}
    {
    }
    const std::int32_t& GetData() const noexcept // Compliant
    {
      return *ownedptr;
    }
 
  private:
    std::unique_ptr<std::int32_t> ownedptr;
};
void Fn3() noexcept
{
  C c{10};
  const std::int32_t& data = c.GetData();
  // data = 20; // Cannot modify data, it is a const reference
}

In this example, GetData() returns a constant reference. You cannot modify private class-data by using this member function. Polyspace does not flag this implementation as noncompliant.

Check Information

Group: Classes
Category: Required, Partially automated

Version History

Introduced in R2019a