rspec/rules/S3229/cfamily/rule.adoc

99 lines
2.4 KiB
Plaintext
Raw Normal View History

== 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.
2021-04-28 16:49:39 +02:00
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
2021-04-28 16:49:39 +02:00
2022-02-04 17:28:24 +01:00
[source,cpp]
2021-04-28 16:49:39 +02:00
----
#include <iostream>
struct A {
A(int num) {
std::cout << "A(num = " << num << ")" << std::endl;
}
};
struct B {
int b;
};
class C : public A, B {
2021-04-28 16:49:39 +02:00
public:
int x;
int y;
C(int i) : B{i}, A{b}, y(i), x(y + 1) { } // Noncompliant
2021-04-28 16:49:39 +02:00
};
int main() {
C c(1); // Undefined behavior, might print "A(num = 0)"
std::cout << c.x << " " << c.y << std::endl; // might print "1 1"
2021-04-28 16:49:39 +02:00
}
----
=== Compliant solution
2022-02-04 17:28:24 +01:00
[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
2021-04-28 16:49:39 +02:00
* 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[]