Skip to content

Commit 046d62c

Browse files
minor improvements to SL.io
1 parent c99a366 commit 046d62c

File tree

1 file changed

+84
-37
lines changed

1 file changed

+84
-37
lines changed

CppCoreGuidelines.md

Lines changed: 84 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# <a name="main"></a>C++ Core Guidelines
22

3-
April 22, 2017
3+
April 24, 2017
44

55

66
Editors:
@@ -589,7 +589,7 @@ Better:
589589

590590
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:
591591

592-
for (auto& x : v) { /* modify x */ }
592+
for (auto& x : v) { /* do to with x */ }
593593

594594
Sometimes better still, use a named algorithm:
595595

@@ -4048,17 +4048,17 @@ For example:
40484048
##### Note
40494049

40504050
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.
40524052

40534053
##### Example
40544054

40554055
A class can provide two interfaces to its users.
40564056
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:
40584058

40594059
class Foo {
40604060
public:
4061-
int bar(int x) { check(x); return do_bar(); }
4061+
int bar(int x) { check(x); return do_bar(); }
40624062
// ...
40634063
protected:
40644064
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
40694069

40704070
class Dir : public Foo {
40714071
//...
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
40774073
}
40784074

40794075
void user(Foo& x)
40804076
{
4081-
int r1 = x.bar(1); // OK, will check
4077+
int r1 = x.bar(1); // OK, will check
40824078
int r2 = x.do_bar(2); // error: would bypass check
40834079
// ...
40844080
}
@@ -6821,14 +6817,14 @@ This kind of "vector" isn't meant to be used as a base class at all.
68216817
Style st;
68226818
};
68236819

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.
68256821
This has been popular, but also a major source of maintenance problems.
68266822
In a large class hierarchy, the consistent use of protected data is hard to maintain because there can be a lot of code,
68276823
spread over a lot of classes.
68286824
The set of classes that can touch that data is open: anyone can derive a new class and start manipulating the protected data.
68296825
Often, it is not possible to examine the complete set of classes so any change to the representation of the class becomes infeasible.
68306826
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.
68326828

68336829
##### Note
68346830

@@ -6964,18 +6960,18 @@ or various bases from boost.intrusive (e.g. `list_base_hook` or `intrusive_ref_c
69646960
};
69656961

69666962
class Derive1 : public Interface, virtual protected Utility {
6967-
// override Interface functions
6963+
// overrride Iterface functions
69686964
// Maybe override Utility virtual functions
69696965
// ...
69706966
};
69716967

69726968
class Derive2 : public Interface, virtual protected Utility {
6973-
// override Interface functions
6969+
// overrride Iterface functions
69746970
// Maybe override Utility virtual functions
69756971
// ...
69766972
};
69776973

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."
69796975

69806976

69816977
##### Note
@@ -6986,7 +6982,7 @@ and `Utility` is the root of an [implementation hierarchy](Rh-kind).
69866982

69876983
##### Note
69886984

6989-
Often, linearization of a hierarchy is a better solution.
6985+
Often, lineraization of a hierarchy is a better solution.
69906986

69916987
##### Enforcement
69926988

@@ -14510,33 +14506,33 @@ Awkward.
1451014506

1451114507
##### Reason
1451214508

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.
1451414510

1451514511
##### Example
1451614512

1451714513
int use(int arg)
14518-
throw(X, Y)
14514+
throw(X,Y)
1451914515
{
1452014516
// ...
1452114517
auto x = f(arg);
1452214518
// ...
1452314519
}
1452414520

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.
1452614522
That's OK, but say that we have checked that this cannot happen and `f` is changed to throw a new exception `Z`,
1452714523
we now have a crash on our hands unless we change `use()` (and re-test everything).
1452814524
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
1452914525
anything about or is in any way interested in.
1453014526
We can change `use()` to pass `Z` through, but now `use()`'s callers probably needs to be modified.
1453114527
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.
1453314529
This too, quickly becomes unmanageable.
1453414530
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.
1453614532
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.
1453814534

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.
1454014536

1454114537
##### Note
1454214538

@@ -14545,7 +14541,7 @@ For example, see [Stroustrup94](#Stroustrup94).
1454514541

1454614542
##### Note
1454714543

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()`.
1454914545

1455014546
##### Enforcement
1455114547

@@ -17391,7 +17387,7 @@ It is more likely to be stable, well-maintained, and widely available than your
1739117387
##### Reason
1739217388

1739317389
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.
1739517391

1739617392
##### Example
1739717393

@@ -17740,7 +17736,10 @@ C++17
1774017736

1774117737
## <a name="SS-io"></a>SL.io: Iostream
1774217738

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).
1774417743

1774517744
Iostream rule summary:
1774617745

@@ -17756,26 +17755,66 @@ Iostream rule summary:
1775617755
##### Reason
1775717756

1775817757
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.
1776017759

1776117760
##### Example
1776217761

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+
???
1776417782

1776517783

1776617784
### <a name="Rio-validate"></a>SL.io.2: When reading, always consider ill-formed input
1776717785

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+
1776817797
???
1776917798

1777017799
### <a name="Rio-streams"></a>SL.io.3: Prefer `iostream`s for I/O
1777117800

1777217801
##### Reason
1777317802

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.
1777517812

1777617813
##### Example
1777717814

17778-
??? complex I/O ???
17815+
// read a file of complex numbers:
17816+
for (complex<double> z; cin>>z)
17817+
v.push_back(z);
1777917818

1778017819
##### Exception
1778117820

@@ -17790,7 +17829,12 @@ implicit memory management, and `locale` handling.
1779017829

1779117830
If you need I/O performance, you can almost always do better than `printf()`.
1779217831

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.
1779317834

17835+
##### Enforcement
17836+
17837+
Optionally flag `<cstdio>` and `<stdio.h>`.
1779417838

1779517839
### <a name="Rio-sync"></a>SL.io.10: Unless you use `printf`-family functions call `ios_base::sync_with_stdio(false)`
1779617840

@@ -17836,11 +17880,14 @@ the choice between `'\n'` and `endl` is almost completely aesthetic.
1783617880

1783717881
## <a name="SS-regex"></a>SL.regex: Regex
1783817882

17839-
???
17883+
`<regex>` is the standard C++ regular experssion library.
17884+
It supports a variety of regular exprssion pattern conventions.
1784017885

1784117886
## <a name="SS-chrono"></a>SL.chrono: Time
1784217887

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`.
1784417891

1784517892
## <a name="SS-clib"></a>SL.C: The C standard library
1784617893

@@ -17860,7 +17907,7 @@ a `longjmp` ignores destructors, thus invalidating all resource-management strat
1786017907

1786117908
##### Enforcement
1786217909

17863-
Flag all occurrences of `longjmp`and `setjmp`
17910+
Flag all occurences of `longjmp`and `setjmp`
1786417911

1786517912

1786617913

@@ -19484,9 +19531,9 @@ Use literal suffixes where clarification is needed
1948419531

1948519532
###### Note
1948619533

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),
1948819535
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.
1949019537

1949119538
###### Enforcement
1949219539

@@ -20643,7 +20690,7 @@ Alternatively, we will decide that no change is needed and delete the entry.
2064320690
\[Meyers15]: S. Meyers. Effective Modern C++ (O'Reilly, 2015).
2064420691
* <a name="Murray93"></a>
2064520692
\[Murray93]: R. Murray. C++ Strategies and Tactics (Addison-Wesley, 1993).
20646-
* <a name="Stroustrup94"></a>
20693+
* <a name="Stroustrup94"></a>
2064720694
\[Stroustrup94]: B. Stroustrup. The Design and Evolution of C++ (Addison-Wesley, 1994).
2064820695
* <a name="Stroustrup00"></a>
2064920696
\[Stroustrup00]: B. Stroustrup. The C++ Programming Language (Special 3rdEdition) (Addison-Wesley, 2000).

0 commit comments

Comments
 (0)