You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: CppCoreGuidelines.md
+84-37Lines changed: 84 additions & 37 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,6 +1,6 @@
1
1
# <a name="main"></a>C++ Core Guidelines
2
2
3
-
April 22, 2017
3
+
April 24, 2017
4
4
5
5
6
6
Editors:
@@ -589,7 +589,7 @@ Better:
589
589
590
590
Now, there is no explicit mention of the iteration mechanism, and the loop operates on a reference to `const` elements so that accidental modification cannot happen. If modification is desired, say so:
591
591
592
-
for (auto& x : v) { /* modify x */ }
592
+
for (auto& x : v) { /* do to with x */ }
593
593
594
594
Sometimes better still, use a named algorithm:
595
595
@@ -4048,17 +4048,17 @@ For example:
4048
4048
##### Note
4049
4049
4050
4050
If the set of direct users of a set of variables cannot be easily determined, the type or usage of that set cannot be (easily) changed/improved.
4051
-
For `public`and `protected` data, that's usually the case.
4051
+
For `public`and `protected` data, that's usually the case.
4052
4052
4053
4053
##### Example
4054
4054
4055
4055
A class can provide two interfaces to its users.
4056
4056
One for derived classes (`protected`) and one for general users (`public`).
4057
-
For example, a derived class might be allowed to skip a run-time check because it has already guaranteed correctness:
4057
+
For example, a derived class might be allowed to skip a run-time check because it has already guarenteed correctness:
4058
4058
4059
4059
class Foo {
4060
4060
public:
4061
-
int bar(int x) { check(x); return do_bar(); }
4061
+
int bar(int x) { check(x); return do_bar(); }
4062
4062
// ...
4063
4063
protected:
4064
4064
int do_bar(int x); // do some operation on the data
@@ -4069,16 +4069,12 @@ For example, a derived class might be allowed to skip a run-time check because i
4069
4069
4070
4070
class Dir : public Foo {
4071
4071
//...
4072
-
int mem(int x, int y)
4073
-
{
4074
-
/* ... do something ... */
4075
-
return do_bar(x+y); // OK: derived class can bypass check
4076
-
}
4072
+
int mem(int x, int y) { /* ... do something ... */ rteurn do_bar(x+y); } // OK: derived class can bypass check
4077
4073
}
4078
4074
4079
4075
void user(Foo& x)
4080
4076
{
4081
-
int r1 = x.bar(1); // OK, will check
4077
+
int r1 = x.bar(1); // OK, will check
4082
4078
int r2 = x.do_bar(2); // error: would bypass check
4083
4079
// ...
4084
4080
}
@@ -6821,14 +6817,14 @@ This kind of "vector" isn't meant to be used as a base class at all.
6821
6817
Style st;
6822
6818
};
6823
6819
6824
-
Now it is up to every derived `Shape` to manipulate the protected data correctly.
6820
+
Now it is up to every defived `Shape` to manipulate the protected data correctly.
6825
6821
This has been popular, but also a major source of maintenance problems.
6826
6822
In a large class hierarchy, the consistent use of protected data is hard to maintain because there can be a lot of code,
6827
6823
spread over a lot of classes.
6828
6824
The set of classes that can touch that data is open: anyone can derive a new class and start manipulating the protected data.
6829
6825
Often, it is not possible to examine the complete set of classes so any change to the representation of the class becomes infeasible.
6830
6826
There is no enforced invariant for the protected data; it is much like a set of global variables.
6831
-
The protected data has de facto become global to a large body of code.
6827
+
The protected data has de-factor become global to a large body of code.
6832
6828
6833
6829
##### Note
6834
6830
@@ -6964,18 +6960,18 @@ or various bases from boost.intrusive (e.g. `list_base_hook` or `intrusive_ref_c
6964
6960
};
6965
6961
6966
6962
class Derive1 : public Interface, virtual protected Utility {
6967
-
// override Interface functions
6963
+
// overrride Iterface functions
6968
6964
// Maybe override Utility virtual functions
6969
6965
// ...
6970
6966
};
6971
6967
6972
6968
class Derive2 : public Interface, virtual protected Utility {
6973
-
// override Interface functions
6969
+
// overrride Iterface functions
6974
6970
// Maybe override Utility virtual functions
6975
6971
// ...
6976
6972
};
6977
6973
6978
-
Factoring out `Utility` makes sense if many derived classes share significant "implementation details."
6974
+
Factoring out `Utility` makes sense if many derived classes share significent "implementation details."
6979
6975
6980
6976
6981
6977
##### Note
@@ -6986,7 +6982,7 @@ and `Utility` is the root of an [implementation hierarchy](Rh-kind).
6986
6982
6987
6983
##### Note
6988
6984
6989
-
Often, linearization of a hierarchy is a better solution.
6985
+
Often, lineraization of a hierarchy is a better solution.
6990
6986
6991
6987
##### Enforcement
6992
6988
@@ -14510,33 +14506,33 @@ Awkward.
14510
14506
14511
14507
##### Reason
14512
14508
14513
-
Exception specifications make error handling brittle, impose a run-time cost, and have been deprecated from the C++ standard.
14509
+
Exception specifications make error handling brittle, impose a run-time cost, and have been removed from the C++ standard.
14514
14510
14515
14511
##### Example
14516
14512
14517
14513
int use(int arg)
14518
-
throw(X,Y)
14514
+
throw(X,Y)
14519
14515
{
14520
14516
// ...
14521
14517
auto x = f(arg);
14522
14518
// ...
14523
14519
}
14524
14520
14525
-
if `f()` throws an exception different from `X` and `Y` the unexpected handler is invoked, which by default terminates.
14521
+
if 'f()' throws an exception different from `X` and `Y` the unexpected handler is invoked, which by default terminates.
14526
14522
That's OK, but say that we have checked that this cannot happen and `f` is changed to throw a new exception `Z`,
14527
14523
we now have a crash on our hands unless we change `use()` (and re-test everything).
14528
14524
The snag is that `f()` may be in a library we do not control and the new exception is not anything that `use()` can do
14529
14525
anything about or is in any way interested in.
14530
14526
We can change `use()` to pass `Z` through, but now `use()`'s callers probably needs to be modified.
14531
14527
This quickly becomes unmanageable.
14532
-
Alternatively, we can add a `try`-`catch` to `use()` to map `Z` into an acceptable exception.
14528
+
Alternatively, we can add a `try`-`catch` to `use()` to map `Z` into an acceptable excption.
14533
14529
This too, quickly becomes unmanageable.
14534
14530
Note that changes to the set of exceptions often happens at the lowest level of a system
14535
-
(e.g., because of changes to a network library or some middleware), so changes "bubble up" through long call chains.
14531
+
(e.g., because of changes to a network library or some middleware), so changes "bubble up" through long call chains.
14536
14532
In a large code base, this could mean that nobody could update to a new version of a library until the last user was modified.
14537
-
If `use()` is part of a library, it may not be possible to update it because a change could affect unknown clients.
14533
+
If `use()` is part of a library, it may not be possible to update it bacause a change could affect unknow clients.
14538
14534
14539
-
The policy of letting exceptions propagate until they reach a function that potentially can handle it has proven itself over the years.
14535
+
The policy of letting exceptions propogate until they reach a function that potentially can handle it has proven itself over the years.
14540
14536
14541
14537
##### Note
14542
14538
@@ -14545,7 +14541,7 @@ For example, see [Stroustrup94](#Stroustrup94).
14545
14541
14546
14542
##### Note
14547
14543
14548
-
If no exception may be thrown, use [`noexcept`](#Re-noexcept)
14544
+
If no exception may be throw, use [`noexcept`](#Re-noexcept) or its equivalent `throw()`.
14549
14545
14550
14546
##### Enforcement
14551
14547
@@ -17391,7 +17387,7 @@ It is more likely to be stable, well-maintained, and widely available than your
17391
17387
##### Reason
17392
17388
17393
17389
Adding to `std` may change the meaning of otherwise standards conforming code.
17394
-
Additions to `std` may clash with future versions of the standard.
17390
+
Additions to `std` may clash with furture versions of the standard.
17395
17391
17396
17392
##### Example
17397
17393
@@ -17740,7 +17736,10 @@ C++17
17740
17736
17741
17737
## <a name="SS-io"></a>SL.io: Iostream
17742
17738
17743
-
???
17739
+
`iostream`s is a type safe, extensible, formatted and unformatted I/O library for streaming I/O.
17740
+
It supports multiple (and user extensible) buffering strategies and multiple locales.
17741
+
It can be used for conventional I/O, reading and writing to memory (string streams),
17742
+
and user-defines extensions, such as streaming across networks (asio: not yet standardized).
17744
17743
17745
17744
Iostream rule summary:
17746
17745
@@ -17756,26 +17755,66 @@ Iostream rule summary:
17756
17755
##### Reason
17757
17756
17758
17757
Unless you genuinely just deal with individual characters, using character-level input leads to the user code performing potentially error-prone
17759
-
and potentially inefficient composition of tokens out of characters.
17758
+
and potentially inefficient composition ot tokens out of characters.
17760
17759
17761
17760
##### Example
17762
17761
17763
-
??? compose a number ???
17762
+
char c;
17763
+
char buf[128];
17764
+
int i = 0;
17765
+
while (cin.get(c) && !isspace(c) && i < 128)
17766
+
buf[i++] = c;
17767
+
if (i == 128) {
17768
+
// ... handle too long string ....
17769
+
}
17770
+
17771
+
Better (much simpler and probably faster):
17772
+
17773
+
string s;
17774
+
s.reserve(128);
17775
+
cin>>s;
17776
+
17777
+
and the `reserve(128)` is probably not worthwhile.
17778
+
17779
+
##### Enforcement
17780
+
17781
+
???
17764
17782
17765
17783
17766
17784
### <a name="Rio-validate"></a>SL.io.2: When reading, always consider ill-formed input
17767
17785
17786
+
##### Reason
17787
+
17788
+
Errors are typically best handled as soon as possible.
17789
+
If input isn't validated, all every function must be writtent to cope with bad data (and that is not practical).
17790
+
17791
+
###### Example
17792
+
17793
+
???
17794
+
17795
+
##### Enforcement
17796
+
17768
17797
???
17769
17798
17770
17799
### <a name="Rio-streams"></a>SL.io.3: Prefer `iostream`s for I/O
17771
17800
17772
17801
##### Reason
17773
17802
17774
-
`iostream`s are safe, flexible, and extensible.
17803
+
`iosteam`s are safe, flexible, and extensible.
17804
+
17805
+
##### Example
17806
+
17807
+
// write a complex number:
17808
+
complex<double> z{ 3,4 };
17809
+
cout << z << '\n';
17810
+
17811
+
`complex` is a user defined type and its I/O is defined without modifying the `iostream` library.
17775
17812
17776
17813
##### Example
17777
17814
17778
-
??? complex I/O ???
17815
+
// read a file of complex numbers:
17816
+
for (complex<double> z; cin>>z)
17817
+
v.push_back(z);
17779
17818
17780
17819
##### Exception
17781
17820
@@ -17790,7 +17829,12 @@ implicit memory management, and `locale` handling.
17790
17829
17791
17830
If you need I/O performance, you can almost always do better than `printf()`.
17792
17831
17832
+
`gets()` `scanf()` using `s`, and `printf()` using `%s` are security hazards (vulnerable to buffer overflow and generally error-prone).
17833
+
In C++11, they are replaced by `gets_s()`, `scanf_s()`, and `printf_s()` as safer alternatives, but they are still not type safe.
17793
17834
17835
+
##### Enforcement
17836
+
17837
+
Optionally flag `<cstdio>` and `<stdio.h>`.
17794
17838
17795
17839
### <a name="Rio-sync"></a>SL.io.10: Unless you use `printf`-family functions call `ios_base::sync_with_stdio(false)`
17796
17840
@@ -17836,11 +17880,14 @@ the choice between `'\n'` and `endl` is almost completely aesthetic.
17836
17880
17837
17881
## <a name="SS-regex"></a>SL.regex: Regex
17838
17882
17839
-
???
17883
+
`<regex>` is the standard C++ regular experssion library.
17884
+
It supports a variety of regular exprssion pattern conventions.
17840
17885
17841
17886
## <a name="SS-chrono"></a>SL.chrono: Time
17842
17887
17843
-
???
17888
+
`<chrono>` (defined in namespace `std::chrono`) provides the notions of `time_point` and `duration` together with functions for
17889
+
outputting time in various units.
17890
+
It provides clocks for registering `time_points`.
17844
17891
17845
17892
## <a name="SS-clib"></a>SL.C: The C standard library
17846
17893
@@ -17860,7 +17907,7 @@ a `longjmp` ignores destructors, thus invalidating all resource-management strat
17860
17907
17861
17908
##### Enforcement
17862
17909
17863
-
Flag all occurrences of `longjmp`and `setjmp`
17910
+
Flag all occurences of `longjmp`and `setjmp`
17864
17911
17865
17912
17866
17913
@@ -19484,9 +19531,9 @@ Use literal suffixes where clarification is needed
19484
19531
19485
19532
###### Note
19486
19533
19487
-
Literals should not be sprinkled all over the code as ["magic constants"](#Res-magic),
19534
+
Literals should not be springled all over the code as ["magic constants'](#Res-magic),
19488
19535
but it is still a good idea to make them readable where they are defined.
19489
-
It is easy to make a typo in a long string of integers.
19536
+
It is easy to make a yypo in a long string of integers.
19490
19537
19491
19538
###### Enforcement
19492
19539
@@ -20643,7 +20690,7 @@ Alternatively, we will decide that no change is needed and delete the entry.
20643
20690
\[Meyers15]: S. Meyers. Effective Modern C++ (O'Reilly, 2015).
20644
20691
* <a name="Murray93"></a>
20645
20692
\[Murray93]: R. Murray. C++ Strategies and Tactics (Addison-Wesley, 1993).
20646
-
* <a name="Stroustrup94"></a>
20693
+
* <a name="Stroustrup94"></a>
20647
20694
\[Stroustrup94]: B. Stroustrup. The Design and Evolution of C++ (Addison-Wesley, 1994).
20648
20695
* <a name="Stroustrup00"></a>
20649
20696
\[Stroustrup00]: B. Stroustrup. The C++ Programming Language (Special 3rdEdition) (Addison-Wesley, 2000).
0 commit comments