From 43bbde7fc9d5846b0715b7d4874745c53a6e0f85 Mon Sep 17 00:00:00 2001 From: hsutter Date: Fri, 3 Jul 2020 17:43:13 -0700 Subject: [PATCH] Committing PR #1640 to main branch --- CppCoreGuidelines.md | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/CppCoreGuidelines.md b/CppCoreGuidelines.md index ac3683b..72e1a75 100644 --- a/CppCoreGuidelines.md +++ b/CppCoreGuidelines.md @@ -1,6 +1,6 @@ # 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 ## 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 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 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 vi; Vector 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::sort()` is called, so it must generate code for it. Similar for `vector::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