Main Content

AUTOSAR C++14 Rule A12-1-5

Common class initialization for non-constant members shall be done by a delegating constructor

Since R2021a

Description

Rule Definition

Common class initialization for non-constant members shall be done by a delegating constructor.

Rationale

C++ classes often have several constructors with different syntaxes. These initializers might have some initializations in common. For instance, in this code, both constructors of the class Circle initialize the nonconstant members x, y and r.

class Circle{
	int x;
	int y;
	int r;
	public:
	Circle(int x_in, int y_in, int r_in): x{x_in}, y{y_in},r{r_in}{
		//...
	}
	Circle( int x_in, int y_in): x{x_in}, y{y_in}, r{0}{
		//...
	}
	//...
};
It is expected that all constructors of a class have equivalent behavior. When these common tasks are performed repeatedly in multiple constructors, any inadvertent differences might lead to confusion and unexpected results. Performing the common tasks repeatedly can also be tedious.

To avoid unexpected results, delegate the initialization of nonconstant members to existing constructors whenever possible. Avoid repeating initializations in multiple constructors.

Polyspace Implementation

Polyspace® flags a class, union, or structure if any of their nonconstant members are initialized in multiple constructors. Polyspace does not flag:

  • Copy or move constructors that do not use delegate constructors.

  • Arrays that are initialized in multiple constructors.

  • Objects that are initialized field by field in multiple constructors.

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 <string>
#include<initializer_list>

class Circle // Noncompliant
{
public:
	Circle(std::int32_t xx, std::int32_t yy, std::int32_t rr):x{xx}, y{yy}, r{rr}
	{}

	Circle(std::int32_t xx, std::int32_t yy):Circle(xx,yy,0) //Delegated constructor
	{}

	Circle(std::int32_t xx):x(xx),y(1),r(1) // Could be delegated
	{}

	Circle():x(0),y(0),r(0)//Could be delegated
	{}

protected:
	std::int32_t x;
	std::int32_t y;
	std::int32_t r;
};
class Flag // Compliant
{
public:
	Flag(bool a):a(a)
	{}

	Flag():a(0)
	{}

protected:
	const bool a;
};

class Tuple    // Noncompliant
{
public:
	Tuple(std::initializer_list<float> ilist) {
		auto* p = ilist.begin(); 
		x = *p++; 
		y = *p++;
		z = *p++;
	}
	Tuple(float _x, float _y, float _z) : x(_x), y(_y), z(_z) {}

	float x = 0, y = 0, z = 0;
};

This example shows compliant and noncompliant classes.

  • The class Circle has four constructors. It delegates the common initializations in the second constructor, but repeats the initializations in the third and fourth constructors. This repetition might lead to unexpected results. Polyspace flags the class.

  • The class Flag repeats the initialization of its member a in two constructors. Because a is a const, Polyspace does not flag the class.

  • The class Tuple initializes its nonconst members repeatedly in two constructors. Polyspace flags the class.

Check Information

Group: Special member functions
Category: Required, Partially automated

Version History

Introduced in R2021a