
Update all links to C++ Core Guidelines to `e49158a`.
Refresh done using the following script and some manual edits:
db76e34e74/personal/fred-tingaud/rspec/refresh-cppcoreguidelines.py
When re-using this script, be mindful that:
- it does not cover `shared_content`
- it does not properly escape inline code in links (e.g., "[=]" or "`mutex`es")
- it does not change `C++` to `{cpp}` in link titles.
Co-authored-by: Marco Borgeaud <marco.borgeaud@sonarsource.com>
99 lines
2.4 KiB
Plaintext
99 lines
2.4 KiB
Plaintext
== Why is this an issue?
|
|
|
|
Class members are initialized in the order in which they are declared in the class,
|
|
not the order in which they appear in the class initializer list.
|
|
To avoid errors caused by order-dependent initialization,
|
|
the order of members in the initialization list should match the order in which members are declared in a class.
|
|
|
|
|
|
The initialization order, as described https://en.cppreference.com/w/cpp/language/constructor#Initialization_order[here], is:
|
|
|
|
. If the constructor is for the most-derived class, virtual bases are initialized in the order in which they appear in depth-first left-to-right traversal of the base class declarations (left-to-right refers to the appearance in base-specifier lists)
|
|
. Then, direct bases are initialized in left-to-right order as they appear in this class's base-specifier list
|
|
. Then, non-static data members are initialized in order of declaration in the class definition.
|
|
|
|
=== Noncompliant code example
|
|
|
|
[source,cpp]
|
|
----
|
|
#include <iostream>
|
|
|
|
struct A {
|
|
A(int num) {
|
|
std::cout << "A(num = " << num << ")" << std::endl;
|
|
}
|
|
};
|
|
|
|
struct B {
|
|
int b;
|
|
};
|
|
|
|
class C : public A, B {
|
|
public:
|
|
int x;
|
|
int y;
|
|
|
|
C(int i) : B{i}, A{b}, y(i), x(y + 1) { } // Noncompliant
|
|
};
|
|
|
|
int main() {
|
|
C c(1); // Undefined behavior, might print "A(num = 0)"
|
|
std::cout << c.x << " " << c.y << std::endl; // might print "1 1"
|
|
}
|
|
----
|
|
|
|
=== Compliant solution
|
|
|
|
[source,cpp]
|
|
----
|
|
#include <iostream>
|
|
|
|
struct A {
|
|
A(int num) {
|
|
std::cout << "A(num = " << num << ")" << std::endl;
|
|
}
|
|
};
|
|
|
|
struct B {
|
|
int b;
|
|
};
|
|
|
|
class C : public A, B {
|
|
public:
|
|
int x;
|
|
int y;
|
|
|
|
C(int i) : A{i}, B{i}, x(i + 1), y(i) { }
|
|
};
|
|
|
|
int main() {
|
|
C c(1); // prints "A(num = 1)"
|
|
std::cout << c.x << " " << c.y << std::endl; // prints "2 1"
|
|
}
|
|
----
|
|
|
|
== Resources
|
|
|
|
* https://wiki.sei.cmu.edu/confluence/x/dXw-BQ[CERT, OOP53-CPP.] - Write constructor member initializers in the canonical order
|
|
* {cpp} Core Guidelines - https://github.com/isocpp/CppCoreGuidelines/blob/e49158a/CppCoreGuidelines.md#c47-define-and-initialize-member-variables-in-the-order-of-member-declaration[C.47: Define and initialize member variables in the order of member declaration]
|
|
|
|
|
|
ifdef::env-github,rspecator-view[]
|
|
|
|
'''
|
|
== Implementation Specification
|
|
(visible only on this page)
|
|
|
|
=== Message
|
|
|
|
Reorder these initializers to match their declaration order.
|
|
|
|
|
|
'''
|
|
== Comments And Links
|
|
(visible only on this page)
|
|
|
|
=== is duplicated by: S1266
|
|
|
|
endif::env-github,rspecator-view[]
|