mirror of
https://github.com/isocpp/CppCoreGuidelines.git
synced 2024-03-22 13:30:58 +08:00
Update CppCoreGuidelines.md
To resolve #1356, cleaned up the text for non-rules, eliminating double negatives
This commit is contained in:
parent
f370b1fa9e
commit
a58ec3ee69
|
@ -19917,20 +19917,20 @@ The positive arguments for alternatives to these non-rules are listed in the rul
|
|||
|
||||
Non-rule summary:
|
||||
|
||||
* [NR.1: Don't: All declarations should be at the top of a function](#Rnr-top)
|
||||
* [NR.2: Don't: Have only a single `return`-statement in a function](#Rnr-single-return)
|
||||
* [NR.3: Don't: Don't use exceptions](#Rnr-no-exceptions)
|
||||
* [NR.4: Don't: Place each class declaration in its own source file](#Rnr-lots-of-files)
|
||||
* [NR.5: Don't: Don't do substantive work in a constructor; instead use two-phase initialization](#Rnr-two-phase-init)
|
||||
* [NR.6: Don't: Place all cleanup actions at the end of a function and `goto exit`](#Rnr-goto-exit)
|
||||
* [NR.7: Don't: Make all data members `protected`](#Rnr-protected-data)
|
||||
* [NR.1: Don't insist that all declarations should be at the top of a function](#Rnr-top)
|
||||
* [NR.2: Don't insist to have only a single `return`-statement in a function](#Rnr-single-return)
|
||||
* [NR.3: Don't avoid exceptions](#Rnr-no-exceptions)
|
||||
* [NR.4: Don't insist on placing each class declaration in its own source file](#Rnr-lots-of-files)
|
||||
* [NR.5: Don't use two-phase initialization](#Rnr-two-phase-init)
|
||||
* [NR.6: Don't place all cleanup actions at the end of a function and `goto exit`](#Rnr-goto-exit)
|
||||
* [NR.7: Don't make all data members `protected`](#Rnr-protected-data)
|
||||
* ???
|
||||
|
||||
### <a name="Rnr-top"></a>NR.1: Don't: All declarations should be at the top of a function
|
||||
### <a name="Rnr-top"></a>NR.1: Don't insist that all declarations should be at the top of a function
|
||||
|
||||
##### Reason (not to follow this rule)
|
||||
##### Reason
|
||||
|
||||
This rule is a legacy of old programming languages that didn't allow initialization of variables and constants after a statement.
|
||||
Th "all declarations on top" rule is a legacy of old programming languages that didn't allow initialization of variables and constants after a statement.
|
||||
This leads to longer programs and more errors caused by uninitialized and wrongly initialized variables.
|
||||
|
||||
##### Example, bad
|
||||
|
@ -19964,9 +19964,9 @@ Unfortunately, compilers cannot catch all such errors and unfortunately, the bug
|
|||
* [Always initialize an object](#Res-always)
|
||||
* [ES.21: Don't introduce a variable (or constant) before you need to use it](#Res-introduce)
|
||||
|
||||
### <a name="Rnr-single-return"></a>NR.2: Don't: Have only a single `return`-statement in a function
|
||||
### <a name="Rnr-single-return"></a>NR.2: Don't insist to have only a single `return`-statement in a function
|
||||
|
||||
##### Reason (not to follow this rule)
|
||||
##### Reason
|
||||
|
||||
The single-return rule can lead to unnecessarily convoluted code and the introduction of extra state variables.
|
||||
In particular, the single-return rule makes it harder to concentrate error checking at the top of a function.
|
||||
|
@ -20034,15 +20034,16 @@ Also, this style is a temptation to use the [goto exit](#Rnr-goto-exit) non-rule
|
|||
* Keep functions short and simple
|
||||
* Feel free to use multiple `return` statements (and to throw exceptions).
|
||||
|
||||
### <a name="Rnr-no-exceptions"></a>NR.3: Don't: Don't use exceptions
|
||||
### <a name="Rnr-no-exceptions"></a>NR.3: Don't avoid exceptions
|
||||
|
||||
##### Reason (not to follow this rule)
|
||||
##### Reason
|
||||
|
||||
There seem to be three main reasons given for this non-rule:
|
||||
There seem to be four main reasons given for not using exceptions:
|
||||
|
||||
* exceptions are inefficient
|
||||
* exceptions lead to leaks and errors
|
||||
* exception performance is not predictable
|
||||
* the exception-handling run-time support takes up too much space
|
||||
|
||||
There is no way we can settle this issue to the satisfaction of everybody.
|
||||
After all, the discussions about exceptions have been going on for 40+ years.
|
||||
|
@ -20078,6 +20079,10 @@ In our opinion, you need RAII to make exception-based error handling simple and
|
|||
If you are in a hard-real-time system where you must guarantee completion of a task in a given time,
|
||||
you need tools to back up such guarantees.
|
||||
As far as we know such tools are not available (at least not to most programmers).
|
||||
* the exception-handling run-time support takes up too much space
|
||||
This can be the case in small (usually embedded systesm).
|
||||
However, before abandoning exceptions consider what space consistent error-handling using error-codes would require
|
||||
and what failure to catch an error would cost.
|
||||
|
||||
Many, possibly most, problems with exceptions stem from historical needs to interact with messy old code.
|
||||
|
||||
|
@ -20103,11 +20108,11 @@ Remember
|
|||
* [RAII](#Re-raii)
|
||||
* Contracts/assertions: Use GSL's `Expects` and `Ensures` (until we get language support for contracts)
|
||||
|
||||
### <a name="Rnr-lots-of-files"></a>NR.4: Don't: Place each class declaration in its own source file
|
||||
### <a name="Rnr-lots-of-files"></a>NR.4: Don't insist on placing each class declaration in its own source file
|
||||
|
||||
##### Reason (not to follow this rule)
|
||||
##### Reason
|
||||
|
||||
The resulting number of files are hard to manage and can slow down compilation.
|
||||
The resulting number of files from placing each class in its own file are hard to manage and can slow down compilation.
|
||||
Individual classes are rarely a good logical unit of maintenance and distribution.
|
||||
|
||||
##### Example
|
||||
|
@ -20118,11 +20123,11 @@ Individual classes are rarely a good logical unit of maintenance and distributio
|
|||
|
||||
* Use namespaces containing logically cohesive sets of classes and functions.
|
||||
|
||||
### <a name="Rnr-two-phase-init"></a>NR.5: Don't: Don't do substantive work in a constructor; instead use two-phase initialization
|
||||
### <a name="Rnr-two-phase-init"></a>NR.5: Don't use two-phase initialization
|
||||
|
||||
##### Reason (not to follow this rule)
|
||||
##### Reason
|
||||
|
||||
Following this rule leads to weaker invariants,
|
||||
Splitting initialization into two rule leads to weaker invariants,
|
||||
more complicated code (having to deal with semi-constructed objects),
|
||||
and errors (when we didn't deal correctly with semi-constructed objects consistently).
|
||||
|
||||
|
@ -20214,9 +20219,9 @@ and errors (when we didn't deal correctly with semi-constructed objects consiste
|
|||
* Always establish a class invariant in a constructor.
|
||||
* Don't define an object before it is needed.
|
||||
|
||||
### <a name="Rnr-goto-exit"></a>NR.6: Don't: Place all cleanup actions at the end of a function and `goto exit`
|
||||
### <a name="Rnr-goto-exit"></a>NR.6: Don't place all cleanup actions at the end of a function and `goto exit`
|
||||
|
||||
##### Reason (not to follow this rule)
|
||||
##### Reason
|
||||
|
||||
`goto` is error-prone.
|
||||
This technique is a pre-exception technique for RAII-like resource and error handling.
|
||||
|
@ -20242,9 +20247,9 @@ and spot the bug.
|
|||
* Use exceptions and [RAII](#Re-raii)
|
||||
* for non-RAII resources, use [`finally`](#Re-finally).
|
||||
|
||||
### <a name="Rnr-protected-data"></a>NR.7: Don't: Make all data members `protected`
|
||||
### <a name="Rnr-protected-data"></a>NR.7: Don't make all data members `protected`
|
||||
|
||||
##### Reason (not to follow this rule)
|
||||
##### Reason
|
||||
|
||||
`protected` data is a source of errors.
|
||||
`protected` data can be manipulated from an unbounded amount of code in various places.
|
||||
|
|
Loading…
Reference in New Issue
Block a user