mirror of
https://github.com/isocpp/CppCoreGuidelines.git
synced 2024-03-22 13:30:58 +08:00
Committing PR #1640 to main branch
This commit is contained in:
parent
ac7079b012
commit
43bbde7fc9
|
@ -1,6 +1,6 @@
|
|||
# <a name="main"></a>C++ Core Guidelines
|
||||
|
||||
May 28, 2020
|
||||
July 3, 2020
|
||||
|
||||
|
||||
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 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
|
||||
and open to interpretation than specify something precisely and wrong.
|
||||
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.
|
||||
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.
|
||||
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").
|
||||
A rule can be part of several profiles, or none.
|
||||
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
|
||||
|
||||
"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);
|
||||
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)).
|
||||
|
@ -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
|
||||
|
||||
|
@ -6710,7 +6710,7 @@ In particular, ensure that an object compares equal to its copy.
|
|||
{
|
||||
Sorted_vector<string> v2 {v};
|
||||
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
|
||||
|
||||
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.
|
||||
|
||||
|
@ -10688,7 +10688,7 @@ Readability. Limit the scope in which a variable can be used. Don't risk used-be
|
|||
|
||||
##### Example, bad
|
||||
|
||||
SomeLargeType var;
|
||||
SomeLargeType var; // Hard-to-read CaMeLcAsEvArIaBlE
|
||||
|
||||
if (cond) // some non-trivial condition
|
||||
Set(&var);
|
||||
|
@ -13433,7 +13433,7 @@ Alternatives for users
|
|||
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.
|
||||
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:
|
||||
|
||||
|
@ -14707,7 +14707,7 @@ Thread creation is expensive.
|
|||
// process
|
||||
}
|
||||
|
||||
void master(istream& is)
|
||||
void dispatcher(istream& is)
|
||||
{
|
||||
for (Message m; is >> 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;
|
||||
|
||||
void master(istream& is)
|
||||
void dispatcher(istream& is)
|
||||
{
|
||||
for (Message m; is >> m; )
|
||||
work.put(m);
|
||||
|
@ -18126,7 +18126,7 @@ Templating a class hierarchy that has many functions, especially many virtual fu
|
|||
Vector<int> vi;
|
||||
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.
|
||||
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.
|
||||
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++
|
||||
(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.
|
||||
|
||||
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 {
|
||||
|
@ -21955,7 +21955,7 @@ Never allow an error to be reported from a destructor, a resource deallocation f
|
|||
|
||||
void test(string& s)
|
||||
{
|
||||
Innocent_bystander i; // more trouble brewing
|
||||
Innocent_bystander i; // more trouble brewing
|
||||
string copy2 = s; // copy the string
|
||||
} // destroy copy and then i
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user