mirror of
https://github.com/isocpp/CppCoreGuidelines.git
synced 2025-12-17 12:44:42 +03:00
Committing PR #1640 to main branch
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
# <a name="main"></a>C++ Core Guidelines
|
# <a name="main"></a>C++ Core Guidelines
|
||||||
|
|
||||||
May 28, 2020
|
July 3, 2020
|
||||||
|
|
||||||
|
|
||||||
Editors:
|
Editors:
|
||||||
@@ -314,7 +314,7 @@ The rules are not value-neutral.
|
|||||||
They are meant to make code simpler and more correct/safer than most existing C++ code, without loss of performance.
|
They are meant to make code simpler and more correct/safer than most existing C++ code, without loss of performance.
|
||||||
They are meant to inhibit perfectly valid C++ code that correlates with errors, spurious complexity, and poor performance.
|
They are meant to inhibit perfectly valid C++ code that correlates with errors, spurious complexity, and poor performance.
|
||||||
|
|
||||||
The rules are not precise to the point where a person (or machine) can follow them blindly.
|
The rules are not precise to the point where a person (or machine) can follow them without thinking.
|
||||||
The enforcement parts try to be that, but we would rather leave a rule or a definition a bit vague
|
The enforcement parts try to be that, but we would rather leave a rule or a definition a bit vague
|
||||||
and open to interpretation than specify something precisely and wrong.
|
and open to interpretation than specify something precisely and wrong.
|
||||||
Sometimes, precision comes only with time and experience.
|
Sometimes, precision comes only with time and experience.
|
||||||
@@ -352,7 +352,7 @@ We try to resolve those using tools.
|
|||||||
Each rule has an **Enforcement** section listing ideas for enforcement.
|
Each rule has an **Enforcement** section listing ideas for enforcement.
|
||||||
Enforcement might be done by code review, by static analysis, by compiler, or by run-time checks.
|
Enforcement might be done by code review, by static analysis, by compiler, or by run-time checks.
|
||||||
Wherever possible, we prefer "mechanical" checking (humans are slow, inaccurate, and bore easily) and static checking.
|
Wherever possible, we prefer "mechanical" checking (humans are slow, inaccurate, and bore easily) and static checking.
|
||||||
Run-time checks are suggested only rarely where no alternative exists; we do not want to introduce "distributed fat".
|
Run-time checks are suggested only rarely where no alternative exists; we do not want to introduce "distributed bloat".
|
||||||
Where appropriate, we label a rule (in the **Enforcement** sections) with the name of groups of related rules (called "profiles").
|
Where appropriate, we label a rule (in the **Enforcement** sections) with the name of groups of related rules (called "profiles").
|
||||||
A rule can be part of several profiles, or none.
|
A rule can be part of several profiles, or none.
|
||||||
For a start, we have a few profiles corresponding to common needs (desires, ideals):
|
For a start, we have a few profiles corresponding to common needs (desires, ideals):
|
||||||
@@ -4724,7 +4724,7 @@ These operations disagree about copy semantics. This will lead to confusion and
|
|||||||
|
|
||||||
## <a name="SS-dtor"></a>C.dtor: Destructors
|
## <a name="SS-dtor"></a>C.dtor: Destructors
|
||||||
|
|
||||||
"Does this class need a destructor?" is a surprisingly powerful design question.
|
"Does this class need a destructor?" is a surprisingly insightful design question.
|
||||||
For most classes the answer is "no" either because the class holds no resources or because destruction is handled by [the rule of zero](#Rc-zero);
|
For most classes the answer is "no" either because the class holds no resources or because destruction is handled by [the rule of zero](#Rc-zero);
|
||||||
that is, its members can take care of themselves as concerns destruction.
|
that is, its members can take care of themselves as concerns destruction.
|
||||||
If the answer is "yes", much of the design of the class follows (see [the rule of five](#Rc-five)).
|
If the answer is "yes", much of the design of the class follows (see [the rule of five](#Rc-five)).
|
||||||
@@ -5561,7 +5561,7 @@ Makes it explicit that the same value is expected to be used in all constructors
|
|||||||
// ...
|
// ...
|
||||||
};
|
};
|
||||||
|
|
||||||
How would a maintainer know whether `j` was deliberately uninitialized (probably a poor idea anyway) and whether it was intentional to give `s` the default value `""` in one case and `qqq` in another (almost certainly a bug)? The problem with `j` (forgetting to initialize a member) often happens when a new member is added to an existing class.
|
How would a maintainer know whether `j` was deliberately uninitialized (probably a bad idea anyway) and whether it was intentional to give `s` the default value `""` in one case and `qqq` in another (almost certainly a bug)? The problem with `j` (forgetting to initialize a member) often happens when a new member is added to an existing class.
|
||||||
|
|
||||||
##### Example
|
##### Example
|
||||||
|
|
||||||
@@ -6710,7 +6710,7 @@ In particular, ensure that an object compares equal to its copy.
|
|||||||
{
|
{
|
||||||
Sorted_vector<string> v2 {v};
|
Sorted_vector<string> v2 {v};
|
||||||
if (v != v2)
|
if (v != v2)
|
||||||
cout << "insanity rules!\n";
|
cout << "Behavior against reason and logic.\n";
|
||||||
// ...
|
// ...
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -8720,7 +8720,7 @@ but at least we can see that something tricky is going on.
|
|||||||
##### Note
|
##### Note
|
||||||
|
|
||||||
Unfortunately, `union`s are commonly used for type punning.
|
Unfortunately, `union`s are commonly used for type punning.
|
||||||
We don't consider "sometimes, it works as expected" a strong argument.
|
We don't consider "sometimes, it works as expected" a conclusive argument.
|
||||||
|
|
||||||
C++17 introduced a distinct type `std::byte` to facilitate operations on raw object representation. Use that type instead of `unsigned char` or `char` for these operations.
|
C++17 introduced a distinct type `std::byte` to facilitate operations on raw object representation. Use that type instead of `unsigned char` or `char` for these operations.
|
||||||
|
|
||||||
@@ -10688,7 +10688,7 @@ Readability. Limit the scope in which a variable can be used. Don't risk used-be
|
|||||||
|
|
||||||
##### Example, bad
|
##### Example, bad
|
||||||
|
|
||||||
SomeLargeType var;
|
SomeLargeType var; // Hard-to-read CaMeLcAsEvArIaBlE
|
||||||
|
|
||||||
if (cond) // some non-trivial condition
|
if (cond) // some non-trivial condition
|
||||||
Set(&var);
|
Set(&var);
|
||||||
@@ -13433,7 +13433,7 @@ Alternatives for users
|
|||||||
This section contains rules for people who need high performance or low-latency.
|
This section contains rules for people who need high performance or low-latency.
|
||||||
That is, these are rules that relate to how to use as little time and as few resources as possible to achieve a task in a predictably short time.
|
That is, these are rules that relate to how to use as little time and as few resources as possible to achieve a task in a predictably short time.
|
||||||
The rules in this section are more restrictive and intrusive than what is needed for many (most) applications.
|
The rules in this section are more restrictive and intrusive than what is needed for many (most) applications.
|
||||||
Do not blindly try to follow them in general code: achieving the goals of low latency requires extra work.
|
Do not naïvely try to follow them in general code: achieving the goals of low latency requires extra work.
|
||||||
|
|
||||||
Performance rule summary:
|
Performance rule summary:
|
||||||
|
|
||||||
@@ -14707,7 +14707,7 @@ Thread creation is expensive.
|
|||||||
// process
|
// process
|
||||||
}
|
}
|
||||||
|
|
||||||
void master(istream& is)
|
void dispatcher(istream& is)
|
||||||
{
|
{
|
||||||
for (Message m; is >> m; )
|
for (Message m; is >> m; )
|
||||||
run_list.push_back(new thread(worker, m));
|
run_list.push_back(new thread(worker, m));
|
||||||
@@ -14719,7 +14719,7 @@ Instead, we could have a set of pre-created worker threads processing the messag
|
|||||||
|
|
||||||
Sync_queue<Message> work;
|
Sync_queue<Message> work;
|
||||||
|
|
||||||
void master(istream& is)
|
void dispatcher(istream& is)
|
||||||
{
|
{
|
||||||
for (Message m; is >> m; )
|
for (Message m; is >> m; )
|
||||||
work.put(m);
|
work.put(m);
|
||||||
@@ -18126,7 +18126,7 @@ Templating a class hierarchy that has many functions, especially many virtual fu
|
|||||||
Vector<int> vi;
|
Vector<int> vi;
|
||||||
Vector<string> vs;
|
Vector<string> vs;
|
||||||
|
|
||||||
It is probably a dumb idea to define a `sort` as a member function of a container, but it is not unheard of and it makes a good example of what not to do.
|
It is probably a bad idea to define a `sort` as a member function of a container, but it is not unheard of and it makes a good example of what not to do.
|
||||||
|
|
||||||
Given this, the compiler cannot know if `vector<int>::sort()` is called, so it must generate code for it.
|
Given this, the compiler cannot know if `vector<int>::sort()` is called, so it must generate code for it.
|
||||||
Similar for `vector<string>::sort()`.
|
Similar for `vector<string>::sort()`.
|
||||||
@@ -20107,7 +20107,7 @@ However, in the context of the styles of programming we recommend and support wi
|
|||||||
|
|
||||||
Even today, there can be contexts where the rules make sense.
|
Even today, there can be contexts where the rules make sense.
|
||||||
For example, lack of suitable tool support can make exceptions unsuitable in hard-real-time systems,
|
For example, lack of suitable tool support can make exceptions unsuitable in hard-real-time systems,
|
||||||
but please don't blindly trust "common wisdom" (e.g., unsupported statements about "efficiency");
|
but please don't naïvely trust "common wisdom" (e.g., unsupported statements about "efficiency");
|
||||||
such "wisdom" may be based on decades-old information or experienced from languages with very different properties than C++
|
such "wisdom" may be based on decades-old information or experienced from languages with very different properties than C++
|
||||||
(e.g., C or Java).
|
(e.g., C or Java).
|
||||||
|
|
||||||
@@ -21945,7 +21945,7 @@ Never allow an error to be reported from a destructor, a resource deallocation f
|
|||||||
|
|
||||||
Here, copying `s` could throw, and if that throws and if `n`'s destructor then also throws, the program will exit via `std::terminate` because two exceptions can't be propagated simultaneously.
|
Here, copying `s` could throw, and if that throws and if `n`'s destructor then also throws, the program will exit via `std::terminate` because two exceptions can't be propagated simultaneously.
|
||||||
|
|
||||||
2. Classes with `Nefarious` members or bases are also hard to use safely, because their destructors must invoke `Nefarious`' destructor, and are similarly poisoned by its poor behavior:
|
2. Classes with `Nefarious` members or bases are also hard to use safely, because their destructors must invoke `Nefarious`' destructor, and are similarly poisoned by its bad behavior:
|
||||||
|
|
||||||
|
|
||||||
class Innocent_bystander {
|
class Innocent_bystander {
|
||||||
|
|||||||
Reference in New Issue
Block a user