Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Always write member initializers in a constructor in the canonical order: first, direct base classes in the order they appear in the base-specifier-list for the class, then nonstatic data members in the order they are declared in the class definition.

Noncompliant Code Example

In this noncompliant code example, the member initializer list for C::C() attempts to initialize SomeVal first, and then initialize DependsOnSomeVal to a value dependent on SomeVal. However, since the declaration order of the member variables does not match the member initializer order, attempting to read the value of SomeVal results in an unspecified value being stored into DependsOnSomeVal.

Code Block
bgColor#FFcccc
langcpp
class C {
  int DependsOnSomeVal;
  int SomeVal;
 
public:
  C(int val) : SomeVal(val), DependsOnSomeVal(SomeVal + 1) {}
};

Compliant Solution

This compliant solution changes the declaration order of the class member variables so that the dependency can be ordered properly in the constructor's member initializer list:

...

Note that it is reasonable for initializers to depend on previously initialized values.

Noncompliant Code Example

In this noncompliant code example, the derived class, D, attempts to initialize the base class, B1, with a value obtained from the base class, B2. However, because B1 is initialized before B2 due to the declaration order in the base class specifier list, the results are undefined.

Code Block
bgColor#FFcccc
langcpp
class B1 {
  int Val;
 
public:
  B1(int V) : Val(V) {}
};

class B2 {
  int OtherVal;
 
public:
  B2(int V) : OtherVal(V) {}
  int getOtherVal() const { return OtherVal; }
};

class D : B1, B2 {
  D(int A) : B2(A), B1(getOtherVal()) {}
};

Compliant Solution

This compliant solution initializes both base classes using the same value from the constructor's parameter list, instead of relying on the initialization order of the base classes:

Code Block
bgColor#ccccff
langcpp
class B1 {
  int Val;
 
public:
  B1(int V) : Val(V) {}
};

class B2 {
  int OtherVal;
 
public:
  B2(int V) : OtherVal(V) {}
};

class D : B1, B2 {
  D(int A) : B1(A), B2(A) {}
};

Risk Assessment

Rule

Severity

Likelihood

Remediation Cost

Priority

Level

OOP37-CPP

Medium

Unlikely

Medium

P4

L3

Automated Detection

Tool

Version

Checker

Description

PRQA QA-C++

 
Include Page
PRQA QA-C++_V
PRQA QA-C++_V

4053,4056,4058

 
Clang
Include Page
Clang_V
Clang_V
-Wreorder 

Related Vulnerabilities

Search for vulnerabilities resulting from the violation of this rule on the CERT website.

Related Guidelines

  

Bibliography

[ISO/IEC 14882-2014]12.6.2, "Initializing Bases and Members"
[Lockheed Martin 05]Rule 75, "Members of the initialization list shall be listed in the order in which they are declared in the class"

...