Main Content

AUTOSAR C++14 Rule A12-1-1

Constructors shall explicitly initialize all virtual base classes, all direct non-virtual base classes and all non-static data members

Description

Rule Definition

Constructors shall explicitly initialize all virtual base classes, all direct non-virtual base classes and all non-static data members.

Rationale

If a derived class does not explicitly initialize the constructors of its base class, then the compiler implicitly initializes the base class. An object of invalid state or an object with unintended initial values might be constructed, which risks unexpected code behavior during run time. Consider this diamond class hierarchy, where the base class Parent has multiple constructors.

class Parent{
	public:
	Parent(){/*...*/}
	Parent(int i){/*...*/}
};

class Child1: public virtual Parent{
	public:
	Child1(): Parent(2){/*...*/}
};

class Child2: public virtual Parent{
	public:
	Child2(): Parent(1){/*...*/}
	
};

class GrandChild: public Child1, public Child2{
	public:
	GrandChild(){/*...*/}
}
When constructing a GrandChild object, it is unclear whether Parent is constructed by using 1 or 2 as the argument. Having GrandChild explicitly specify the constructor used to initialize the Parent resolves the ambiguity. To avoid invalid state and unintended initial values, directly call the necessary base class constructors in the derived class constructor initialization list.

Polyspace Implementation

Polyspace® flags the constructor of a derived class if its initialization list:

  • Does not explicitly call the constructors of the virtual base classes.

  • Does not explicitly call the constructors of the direct nonvirtual base classes.

  • Does not explicitly initialize nonstatic data members.

If a nonstatic data member is initialized in at least one branch of a branching, looping, or exception handling statement, Polyspace considers the data member to be initialized.

Polyspace does not report a violation of this rule if you use delegating 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>    

class A {  
public:  
	A() : a{1} {}  
	virtual void abstractA() const = 0;  
private:  
	int a;  
};  

class B : public  A {  
public:  
	B() : b{1} {} //Noncompliant 
	void abstractA() const override {}  
private:  
	int b;  
};  

class C {  
public:  
	C() : c{3} {}  
private:  
	int c;  
};  

class D : public B, public C {  
public:  
	D() : B(), C(), e{5} {} //Compliant 
private:  
	int e;  
};  

int main() {   
	D dName;  
	return 0;   
} 

In this example, Polyspace flags the class constructors that do not explicitly initialize the base classes and nonstatic data members. For instance:

  • The B class constructor is noncompliant because it is missing an explicit initialization of its base class A. To resolve this issue, call the A class constructor in the B constructor initialization list.

  • The D class constructor is compliant because it explicitly initializes both of its direct nonvirtual base classes through initialization list constructor calls.

#include <cstdint>   
class A { 
public: 
	A() : a{1} {} 
	virtual void abstractA() const = 0; 
private: 
	int a; 
}; 


class B : public virtual A { 
public: 
	B() : A(), b{1} {} //Compliant 
	void abstractA() const override {} 
private: 
	int b; 

}; 


class C : public virtual A { 
public: 
	C() : c{3} {} //Noncompliant 
	void abstractA() const override {} 
private: 
	int c; 
}; 


class D : public B, public C { 
public: 

	D() : B(), C(), e{5} {} //Noncompliant 
private: 
	int e; 
}; 



int main() {  
	D dName; 
	return 0;  
} 

In this example, Polyspace flags the class constructors that do not explicitly initialize the base classes and nonstatic data members. For instance:

  • The B class constructor is compliant because it explicitly initializes its direct base class within its initialization list.

  • The C class constructor is noncompliant because it does not explicitly call its direct base class A. To resolve this issue, call the A class constructor in the C constructor initialization list.

  • The D class constructor is noncompliant because it does not explicitly call its virtual base class A. As a result of multiple and virtual inheritance, the most derived class must initialize the virtual base class. To resolve this issue, call the A class constructor in the D constructor initialization list.

In C++11 and later, if a class contains more than one constructors, the class design can be simplified by using delegating constructor. When you use delegating constructors, it is not necessary to initialize all data members and base classes in each constructor. In this example, Polyspace does not report violations of this rule when the constructor Derived::Derived(int) delegates its initialization duties to Derived::Derived(int, int).

class Base {
public:
	Base() : a{1} {}                    

	virtual void abstractA() const = 0;

private:
	int a;
};
class Derived: public Base {
public:
	Derived(int a, int b): Base{}, z{a}, y{b} {}  //Compliant
	Derived(int a): Derived(a, 0) {}  //Compliant

private:
	int z;
	int y;
};

Check Information

Group: Special Member Functions
Category: Required, Automated

Version History

Introduced in R2019a

expand all