Main Content

AUTOSAR C++14 Rule A12-1-2

Both NSDMI and a non-static member initializer in a constructor shall not be used in the same type

Since R2020b

Description

Rule Definition

Both NSDMI and a non-static member initializer in a constructor shall not be used in the same type.

Rationale

You can initialize a non-static data member of a class in one of these ways:

  • In the declaration of the member in the class body by using the non-static data member initializer (NSDMI)

  • By using a non-static member initializer in a constructor

In a class, initializing a subset of the non-static data members by using the NSDMI and initializing the remaining non-static data members by using a constructor reduces code readability. This code pattern might cause confusion for the reader about which initial values for each data member are actually used. Using either the NSDMI or a constructor to initialize all non-static data members of the class avoids this potential confusion.

The move and copy constructors are exempt from this rule because these constructors have the special behavior of initializing the data members by using their existing values from other objects. These constructors are unlikely to cause the confusion for the reader.

Polyspace Implementation

If you use the NSDMI to initialize a subset of the non-static data members of a class and a constructor to initialize the remaining non-static data members, the checker flags the constructor and the associated NSDMI initializations.

The checker does not flag the move and copy constructors that violate this rule.

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

class A
{
  public:
    A() : i1{0}, i2{0} // Compliant, i1 and i2 are initialized by the constructor only
    {
    }
	
  private:
    std::int32_t i1;
    std::int32_t i2;
};

class B
{
  private:
    std::int32_t i1{0};
    std::int32_t i2{0}; // Compliant, i1 and i2 are initialized by NSDMI only
};

class C
{
  public:
    C() : i2{0}   // Noncompliant, i1 is initialized by NSDMI, i2 is initialized by constructor
    {
    }

  private:
    std::int32_t i1{0};
    std::int32_t i2;
};

class D
{
    D(D const& oth) : i1{oth.i1}, i2{oth.i2} // Compliant by exception, copy constructor
    {
    }

    D(D&& oth): i1{std::move(oth.i1)}, i2{std::move(oth.i2)} 
    // Compliant by exception, move constructor
    {
    }

  private:
    std::int32_t i1{0};
    std::int32_t i2{0};
};

In this code, only the constructor in class C does not comply with this coding rule because:

  • The data member i1 is initialized by using the NSDMI.

  • The data member i2 is initialized in the constructor.

Check Information

Group: Special member functions
Category: Required, Automated

Version History

Introduced in R2020b

expand all