Main Content

AUTOSAR C++14 Rule A11-0-1

A non-POD type should be defined as class

Since R2020b

Description

Rule Definition

A non-POD type should be defined as class.

Rationale

A POD (Plain Old Data) type can be exchanged with C code in its binary form, and can be safely copied by using the std::memcpy function. Scalar types, C-style structures and unions, and arrays of these types are all examples of POD types. However, the C++ language also allows you to create structures and unions that are non-POD types. Such structures and unions can provide custom-defined constructors, have nonstatic data members with private or protected access control, have an interface, and implement an invariant.

A software developer typically expects object-oriented concepts such as encapsulation to be implemented by using classes. In addition, a class specifier forces the type to provide private access control for all its members by default and is naturally suited for implementing encapsulated types. So, to create easily readable and maintainable code, define a non-POD type as a class instead of a structure or a union.

Polyspace Implementation

The checker flags a structure or a union in your code is not a POD type. This includes structures and unions that are instantiated by using templates.

For a simplified explanation of a POD type in C++ language, see the previous section. For a full specification of a POD type, see the C++ reference manual.

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 <limits>

class A // Compliant, non-POD type defined as class
{
    std::int32_t x; // Data member is private by default

  public:
    static constexpr std::int32_t maxValue = std::numeric_limits<std::int32_t>::max();
    A() : x(maxValue) {}
    explicit A(std::int32_t number) : x(number) {}

    std::int32_t GetX() const noexcept
    {
      return x;
    }
	
    void SetX(std::int32_t number) noexcept
    {
      x = number;
    }
};

struct B // Noncompliant, non-POD type defined as struct
{ 
  private:
    std::int32_t x;  // Must provide private access specifier for x member
	
  public:
    static constexpr std::int32_t maxValue = std::numeric_limits<std::int32_t>::max();
    B() : x(maxValue) {}
    explicit B(std::int32_t number) : x(number) {}

    std::int32_t GetX() const noexcept
    {
      return x;
    }
	
    void SetX(std::int32_t number) noexcept
    {
      x = number;
    }
};

Both class A and struct B implement the same non-POD type. This type has:

  • A nonstatic data member x that has private access control.

  • Two user-defined constructors. The default constructor initializes x to the maximum value that an int32 type can store. The constructor that has one parameter disallows implicit conversion.

  • An interface provided by the GetX and the SetX methods to access and modify the state of an object.

It is preferable that you implement this type, that encapsulates its contents, as a class.

The definition of class A complies with this coding rule. The definition of struct B violates this coding rule.

Check Information

Group: Member access control
Category: Advisory, Automated

Version History

Introduced in R2020b