mirror of
https://github.com/isocpp/CppCoreGuidelines.git
synced 2025-12-17 12:44:42 +03:00
Consistent use of double-hyphen for en-dash.
Use `--` for all occurrences of en-dashes. All UTF-8 dashes are reduced to this convention. Let the Markdown renderer cope with the correct expansion of such items, e.g., `pandoc --smart ...`.
This commit is contained in:
committed by
Thibault Kruse
parent
d092b19fc7
commit
b83449a33b
@@ -101,7 +101,7 @@ In other words, what would you like your code to look like in 5 years' time, giv
|
||||
The guidelines are focused on relatively higher-level issues, such as interfaces, resource management, memory management, and concurrency.
|
||||
Such rules affect application architecture and library design.
|
||||
Following the rules will lead to code that is statically type safe, has no resource leaks, and catches many more programming logic errors than is common in code today.
|
||||
And it will run fast - you can afford to do things right.
|
||||
And it will run fast -- you can afford to do things right.
|
||||
|
||||
We are less concerned with low-level issues, such as naming conventions and indentation style.
|
||||
However, no topic that can help a programmer is out of bounds.
|
||||
@@ -263,18 +263,18 @@ name of a profile group-of-rules ("type", "bounds", or "lifetime"), or a specifi
|
||||
|
||||
Each rule (guideline, suggestion) can have several parts:
|
||||
|
||||
* The rule itself - e.g., **no naked `new`**
|
||||
* A rule reference number - e.g., **C.7** (the 7th rule related to classes).
|
||||
* The rule itself -- e.g., **no naked `new`**
|
||||
* A rule reference number -- e.g., **C.7** (the 7th rule related to classes).
|
||||
Since the major sections are not inherently ordered, we use a letter as the first part of a rule reference "number".
|
||||
We leave gaps in the numbering to minimize "disruption" when we add or remove rules.
|
||||
* **Reason**s (rationales) - because programmers find it hard to follow rules they don't understand
|
||||
* **Example**s - because rules are hard to understand in the abstract; can be positive or negative
|
||||
* **Alternative**s - for "don't do this" rules
|
||||
* **Exception**s - we prefer simple general rules. However, many rules apply widely, but not universally, so exceptions must be listed
|
||||
* **Enforcement** - ideas about how the rule might be checked "mechanically"
|
||||
* **See also**s - references to related rules and/or further discussion (in this document or elsewhere)
|
||||
* **Note**s (comments) - something that needs saying that doesn't fit the other classifications
|
||||
* **Discussion** - references to more extensive rationale and/or examples placed outside the main lists of rules
|
||||
* **Reason**s (rationales) -- because programmers find it hard to follow rules they don't understand
|
||||
* **Example**s -- because rules are hard to understand in the abstract; can be positive or negative
|
||||
* **Alternative**s -- for "don't do this" rules
|
||||
* **Exception**s -- we prefer simple general rules. However, many rules apply widely, but not universally, so exceptions must be listed
|
||||
* **Enforcement** -- ideas about how the rule might be checked "mechanically"
|
||||
* **See also**s -- references to related rules and/or further discussion (in this document or elsewhere)
|
||||
* **Note**s (comments) -- something that needs saying that doesn't fit the other classifications
|
||||
* **Discussion** -- references to more extensive rationale and/or examples placed outside the main lists of rules
|
||||
|
||||
Some rules are hard to check mechanically, but they all meet the minimal criteria that an expert programmer can spot many violations without too much trouble.
|
||||
We hope that "mechanical" tools will improve with time to approximate what such an expert programmer notices.
|
||||
@@ -540,11 +540,11 @@ We can ban, restrain, or detect the individual problem categories separately, as
|
||||
Always suggest an alternative.
|
||||
For example:
|
||||
|
||||
* unions - use `variant`
|
||||
* casts - minimize their use; templates can help
|
||||
* array decay - use `span`
|
||||
* range errors - use `span`
|
||||
* narrowing conversions - minimize their use and use `narrow` or `narrow_cast` where they are necessary
|
||||
* unions -- use `variant`
|
||||
* casts -- minimize their use; templates can help
|
||||
* array decay -- use `span`
|
||||
* range errors -- use `span`
|
||||
* narrowing conversions -- minimize their use and use `narrow` or `narrow_cast` where they are necessary
|
||||
|
||||
### <a name="Rp-compile-time"></a>P.5: Prefer compile-time checking to run-time checking
|
||||
|
||||
@@ -1156,7 +1156,7 @@ Obviously, we cannot catch all errors through the static type system
|
||||
|
||||
In the following example, it is not clear from the interface what `time_to_blink` means: Seconds? Milliseconds?
|
||||
|
||||
void blink_led(int time_to_blink) // bad - the unit is ambiguous
|
||||
void blink_led(int time_to_blink) // bad -- the unit is ambiguous
|
||||
{
|
||||
// ...
|
||||
// do something with time_to_blink
|
||||
@@ -1172,7 +1172,7 @@ In the following example, it is not clear from the interface what `time_to_blink
|
||||
|
||||
`std::chrono::duration` types introduced in C++11 helps making the unit of time duration explicit.
|
||||
|
||||
void blink_led(milliseconds time_to_blink) // good - the unit is explicit
|
||||
void blink_led(milliseconds time_to_blink) // good -- the unit is explicit
|
||||
{
|
||||
// ...
|
||||
// do something with time_to_blink
|
||||
@@ -1187,7 +1187,7 @@ In the following example, it is not clear from the interface what `time_to_blink
|
||||
The function can also be written in such a way that it will accept any time duration unit.
|
||||
|
||||
template<class rep, class period>
|
||||
void blink_led(duration<rep, period> time_to_blink) // good - accepts any unit
|
||||
void blink_led(duration<rep, period> time_to_blink) // good -- accepts any unit
|
||||
{
|
||||
// assuming that millisecond is the smallest relevant unit
|
||||
auto milliseconds_to_blink = duration_cast<milliseconds>(time_to_blink);
|
||||
@@ -3056,7 +3056,7 @@ principle of "do as the ints do."
|
||||
##### Note
|
||||
|
||||
Historically there was some guidance to make the assignment operator return `const T&`.
|
||||
This was primarily to avoid code of the form `(a=b)=c` - such code is not common enough to warrant violating consistency with standard types.
|
||||
This was primarily to avoid code of the form `(a=b)=c` -- such code is not common enough to warrant violating consistency with standard types.
|
||||
|
||||
##### Example
|
||||
|
||||
@@ -6241,7 +6241,7 @@ Some people use `dynamic_cast` where a `typeid` would have been more appropriate
|
||||
`dynamic_cast` is a general "is kind of" operation for discovering the best interface to an object,
|
||||
whereas `typeid` is a "give me the exact type of this object" operation to discover the actual type of an object.
|
||||
The latter is an inherently simpler operation that ought to be faster.
|
||||
The latter (`typeid`) is easily hand-crafted if necessary (e.g., if working on a system where RTTI is - for some reason - prohibited),
|
||||
The latter (`typeid`) is easily hand-crafted if necessary (e.g., if working on a system where RTTI is -- for some reason -- prohibited),
|
||||
the former (`dynamic_cast`) is far harder to implement correctly in general.
|
||||
|
||||
Consider:
|
||||
@@ -7730,7 +7730,7 @@ This makes the function's ownership sharing explicit.
|
||||
|
||||
##### Example, good
|
||||
|
||||
void share(shared_ptr<widget>); // share – "will" retain refcount
|
||||
void share(shared_ptr<widget>); // share -- "will" retain refcount
|
||||
|
||||
void reseat(shared_ptr<widget>&); // "might" reseat ptr
|
||||
|
||||
@@ -7754,7 +7754,7 @@ This makes the function's reseating explicit.
|
||||
|
||||
##### Example, good
|
||||
|
||||
void share(shared_ptr<widget>); // share – "will" retain refcount
|
||||
void share(shared_ptr<widget>); // share -- "will" retain refcount
|
||||
|
||||
void reseat(shared_ptr<widget>&); // "might" reseat ptr
|
||||
|
||||
@@ -7774,7 +7774,7 @@ This makes the function's ??? explicit.
|
||||
|
||||
##### Example, good
|
||||
|
||||
void share(shared_ptr<widget>); // share – "will" retain refcount
|
||||
void share(shared_ptr<widget>); // share -- "will" retain refcount
|
||||
|
||||
void reseat(shared_ptr<widget>&); // "might" reseat ptr
|
||||
|
||||
@@ -8390,7 +8390,7 @@ Many such errors are introduced during maintenance years after the initial imple
|
||||
##### Exception
|
||||
|
||||
It you are declaring an object that is just about to be initialized from input, initializing it would cause a double initialization.
|
||||
However, beware that this may leave uninitialized data beyond the input - and that has been a fertile source of errors and security breaches:
|
||||
However, beware that this may leave uninitialized data beyond the input -- and that has been a fertile source of errors and security breaches:
|
||||
|
||||
constexpr int max = 8 * 1024;
|
||||
int buf[max]; // OK, but suspicious: uninitialized
|
||||
@@ -9760,7 +9760,7 @@ This example has many more problems.
|
||||
|
||||
##### Reason
|
||||
|
||||
Slicing - that is, copying only part of an object using assignment or initialization - most often leads to errors because
|
||||
Slicing -- that is, copying only part of an object using assignment or initialization -- most often leads to errors because
|
||||
the object was meant to be considered as a whole.
|
||||
In the rare cases where the slicing was deliberate the code can be surprising.
|
||||
|
||||
@@ -14140,8 +14140,8 @@ Dynamic accesses into arrays are difficult for both tools and humans to validate
|
||||
{
|
||||
a[pos / 2] = 1; // BAD
|
||||
a[pos - 1] = 2; // BAD
|
||||
a[-1] = 3; // BAD - no replacement, just don't do this
|
||||
a[10] = 4; // BAD - no replacement, just don't do this
|
||||
a[-1] = 3; // BAD -- no replacement, just don't do this
|
||||
a[10] = 4; // BAD -- no replacement, just don't do this
|
||||
}
|
||||
|
||||
##### Example, good
|
||||
@@ -14211,7 +14211,7 @@ Issue a diagnostic for any indexing expression on an expression or variable of a
|
||||
void f(int i, int j)
|
||||
{
|
||||
a[i + j] = 12; // BAD, could be rewritten as ...
|
||||
at(a, i + j) = 12; // OK - bounds-checked
|
||||
at(a, i + j) = 12; // OK -- bounds-checked
|
||||
}
|
||||
|
||||
### <a name="Pro-bounds-decay"></a>Bounds.3: No array-to-pointer decay.
|
||||
@@ -14242,7 +14242,7 @@ Pointers should not be used as arrays. `span` is a bounds-checked, safe alternat
|
||||
span av = a;
|
||||
|
||||
g(a.data(), a.length()); // OK, if you have no choice
|
||||
g1(a); // OK - no decay here, instead use implicit span ctor
|
||||
g1(a); // OK -- no decay here, instead use implicit span ctor
|
||||
}
|
||||
|
||||
##### Enforcement
|
||||
|
||||
Reference in New Issue
Block a user