code fixes

This commit is contained in:
Thibault Kruse 2017-06-14 00:25:03 +09:00
parent 22c305fdee
commit b02eb91b84

View File

@ -4222,7 +4222,7 @@ For example, a derived class might be allowed to skip a run-time check because i
class Foo { class Foo {
public: public:
int bar(int x) { check(x); return do_bar(); } int bar(int x) { check(x); return do_bar(x); }
// ... // ...
protected: protected:
int do_bar(int x); // do some operation on the data int do_bar(int x); // do some operation on the data
@ -4238,7 +4238,7 @@ For example, a derived class might be allowed to skip a run-time check because i
/* ... do something ... */ /* ... do something ... */
return do_bar(x + y); // OK: derived class can bypass check return do_bar(x + y); // OK: derived class can bypass check
} }
} };
void user(Foo& x) void user(Foo& x)
{ {
@ -7611,10 +7611,12 @@ It also gives an opportunity to eliminate a separate allocation for the referenc
##### Example ##### Example
// OK: but repetitive; and separate allocations for the Foo and shared_ptr's use count void test() {
shared_ptr<Foo> p {new<Foo>{7}}; // OK: but repetitive; and separate allocations for the Bar and shared_ptr's use count
shared_ptr<Bar> p {new<Bar>{7}};
auto q = make_shared<Foo>(7); // Better: no repetition of Foo; one object auto q = make_shared<Bar>(7); // Better: no repetition of Bar; one object
}
##### Enforcement ##### Enforcement
@ -8980,7 +8982,7 @@ If you don't, an exception or a return may lead to a leak.
{ {
FILE* f = fopen(name, "r"); // open the file FILE* f = fopen(name, "r"); // open the file
vector<char> buf(1024); vector<char> buf(1024);
auto _ = finally([f] { fclose(f); }) // remember to close the file auto _ = finally([f] { fclose(f); }); // remember to close the file
// ... // ...
} }
@ -10914,7 +10916,7 @@ There is a fair amount of use of the C goto-exit idiom:
goto exit; goto exit;
// ... // ...
exit: exit:
... common cleanup code ... // ... common cleanup code ...
} }
This is an ad-hoc simulation of destructors. This is an ad-hoc simulation of destructors.
@ -11367,7 +11369,7 @@ Use a `span`:
void f2(array<int, 10> arr, int pos) // A2: Add local span and use that void f2(array<int, 10> arr, int pos) // A2: Add local span and use that
{ {
span<int> a = {arr, pos} span<int> a = {arr, pos};
a[pos / 2] = 1; // OK a[pos / 2] = 1; // OK
a[pos - 1] = 2; // OK a[pos - 1] = 2; // OK
} }
@ -12248,7 +12250,7 @@ The conventional resolution is to interpret `{10}` as a list of one element and
This mistake need not be repeated in new code. This mistake need not be repeated in new code.
We can define a type to represent the number of elements: We can define a type to represent the number of elements:
struct Count { int n }; struct Count { int n; };
template<typename T> template<typename T>
class Vector { class Vector {
@ -12670,7 +12672,7 @@ For example
operator int() { return val; } operator int() { return val; }
}; };
int f(Positive arg) {return arg }; int f(Positive arg) { return arg; }
int r1 = f(2); int r1 = f(2);
int r2 = f(-2); // throws int r2 = f(-2); // throws
@ -13321,7 +13323,7 @@ The less sharing you do, the less chance you have to wait on a lock (so performa
socket1 >> surface_readings; socket1 >> surface_readings;
if (!socket1) throw Bad_input{}; if (!socket1) throw Bad_input{};
auto h1 = async([&] { if (!validate(surface_readings) throw Invalid_data{}; }); auto h1 = async([&] { if (!validate(surface_readings)) throw Invalid_data{}; });
auto h2 = async([&] { return temperature_gradiants(surface_readings); }); auto h2 = async([&] { return temperature_gradiants(surface_readings); });
auto h3 = async([&] { return altitude_map(surface_readings); }); auto h3 = async([&] { return altitude_map(surface_readings); });
// ... // ...
@ -13887,7 +13889,7 @@ message passing or shared memory.
??? ???
### <a name="Rconc-shared"></a>[CP.32: To share ownership between unrelated `thread`s use `shared_ptr` ### <a name="Rconc-shared"></a>CP.32: To share ownership between unrelated `thread`s use `shared_ptr`
##### Reason ##### Reason
@ -14990,12 +14992,14 @@ To prevent slicing.
##### Example ##### Example
void f() void f()
{
try { try {
// ... // ...
} }
catch (exception e) { // don't: may slice catch (exception e) { // don't: may slice
// ... // ...
} }
}
Instead, use a reference: Instead, use a reference:
@ -15592,7 +15596,7 @@ You can
Example: Example:
void f(int* p); // old code: f() does not modify `*p` void f(int* p); // old code: f() does not modify `*p`
void f(const int* p) { f(const_cast<int*>(p); } // wrapper void f(const int* p) { f(const_cast<int*>(p)); } // wrapper
Note that this wrapper solution is a patch that should be used only when the declaration of `f()` cannot be be modified, Note that this wrapper solution is a patch that should be used only when the declaration of `f()` cannot be be modified,
e.g. because it is in a library that you cannot modify. e.g. because it is in a library that you cannot modify.
@ -16296,7 +16300,7 @@ It is a general design rule that even applies to non-templates:
void f(const Minimal& x, const Minimal& y) void f(const Minimal& x, const Minimal& y)
{ {
if (!(x == y) { /* ... */ } // OK if (!(x == y)) { /* ... */ } // OK
if (x != y) { /* ... */ } // surprise! error if (x != y) { /* ... */ } // surprise! error
while (!(x < y)) { /* ... */ } // OK while (!(x < y)) { /* ... */ } // OK
@ -16326,7 +16330,7 @@ The rule supports the view that a concept should reflect a (mathematically) cohe
void f(const Convenient& x, const Convenient& y) void f(const Convenient& x, const Convenient& y)
{ {
if (!(x == y) { /* ... */ } // OK if (!(x == y)) { /* ... */ } // OK
if (x != y) { /* ... */ } // OK if (x != y) { /* ... */ } // OK
while (!(x < y)) { /* ... */ } // OK while (!(x < y)) { /* ... */ } // OK
@ -18690,7 +18694,7 @@ Don't use C-style strings for operations that require non-trivial memory managem
p[l1] = '.'; p[l1] = '.';
strcpy(p + l1 + 1, s2, l2); strcpy(p + l1 + 1, s2, l2);
p[l1 + l2 + 1] = 0; p[l1 + l2 + 1] = 0;
return res; return p;
} }
Did we get that right? Did we get that right?