@@ -4222,7 +4222,7 @@ For example, a derived class might be allowed to skip a run-time check because i
4222
4222
4223
4223
class Foo {
4224
4224
public:
4225
- int bar(int x) { check(x); return do_bar(); }
4225
+ int bar(int x) { check(x); return do_bar(x ); }
4226
4226
// ...
4227
4227
protected:
4228
4228
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
4238
4238
/* ... do something ... */
4239
4239
return do_bar(x + y); // OK: derived class can bypass check
4240
4240
}
4241
- }
4241
+ };
4242
4242
4243
4243
void user(Foo& x)
4244
4244
{
@@ -7126,7 +7126,7 @@ If the operations are virtual the use of inheritance is necessary, if not using
7126
7126
7127
7127
##### Example
7128
7128
7129
- class iostream : public istream, public ostream { // very simplified
7129
+ class iostream : public istream, public ostream { // very simplified
7130
7130
// ...
7131
7131
};
7132
7132
@@ -7611,10 +7611,12 @@ It also gives an opportunity to eliminate a separate allocation for the referenc
7611
7611
7612
7612
##### Example
7613
7613
7614
- // OK: but repetitive; and separate allocations for the Foo and shared_ptr's use count
7615
- shared_ptr<Foo> p {new<Foo>{7}};
7614
+ void test() {
7615
+ // OK: but repetitive; and separate allocations for the Bar and shared_ptr's use count
7616
+ shared_ptr<Bar> p {new<Bar>{7}};
7616
7617
7617
- auto q = make_shared<Foo>(7); // Better: no repetition of Foo; one object
7618
+ auto q = make_shared<Bar>(7); // Better: no repetition of Bar; one object
7619
+ }
7618
7620
7619
7621
##### Enforcement
7620
7622
@@ -8978,9 +8980,9 @@ If you don't, an exception or a return may lead to a leak.
8978
8980
8979
8981
void f(const string& name)
8980
8982
{
8981
- FILE* f = fopen(name, "r"); // open the file
8983
+ FILE* f = fopen(name, "r"); // open the file
8982
8984
vector<char> buf(1024);
8983
- auto _ = finally([f] { fclose(f); }) // remember to close the file
8985
+ auto _ = finally([f] { fclose(f); }); // remember to close the file
8984
8986
// ...
8985
8987
}
8986
8988
@@ -10914,7 +10916,7 @@ There is a fair amount of use of the C goto-exit idiom:
10914
10916
goto exit;
10915
10917
// ...
10916
10918
exit:
10917
- ... common cleanup code ...
10919
+ // ... common cleanup code ...
10918
10920
}
10919
10921
10920
10922
This is an ad-hoc simulation of destructors.
@@ -11367,7 +11369,7 @@ Use a `span`:
11367
11369
11368
11370
void f2(array<int, 10> arr, int pos) // A2: Add local span and use that
11369
11371
{
11370
- span<int> a = {arr, pos}
11372
+ span<int> a = {arr, pos};
11371
11373
a[pos / 2] = 1; // OK
11372
11374
a[pos - 1] = 2; // OK
11373
11375
}
@@ -12248,7 +12250,7 @@ The conventional resolution is to interpret `{10}` as a list of one element and
12248
12250
This mistake need not be repeated in new code.
12249
12251
We can define a type to represent the number of elements:
12250
12252
12251
- struct Count { int n };
12253
+ struct Count { int n; };
12252
12254
12253
12255
template<typename T>
12254
12256
class Vector {
@@ -12670,7 +12672,7 @@ For example
12670
12672
operator int() { return val; }
12671
12673
};
12672
12674
12673
- int f(Positive arg) {return arg };
12675
+ int f(Positive arg) { return arg; }
12674
12676
12675
12677
int r1 = f(2);
12676
12678
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
13321
13323
socket1 >> surface_readings;
13322
13324
if (!socket1) throw Bad_input{};
13323
13325
13324
- auto h1 = async([&] { if (!validate(surface_readings) throw Invalid_data{}; });
13326
+ auto h1 = async([&] { if (!validate(surface_readings)) throw Invalid_data{}; });
13325
13327
auto h2 = async([&] { return temperature_gradiants(surface_readings); });
13326
13328
auto h3 = async([&] { return altitude_map(surface_readings); });
13327
13329
// ...
@@ -13887,7 +13889,7 @@ message passing or shared memory.
13887
13889
???
13888
13890
13889
13891
13890
- ### <a name="Rconc-shared"></a>[ CP.32: To share ownership between unrelated `thread`s use `shared_ptr`
13892
+ ### <a name="Rconc-shared"></a>CP.32: To share ownership between unrelated `thread`s use `shared_ptr`
13891
13893
13892
13894
##### Reason
13893
13895
@@ -14709,7 +14711,7 @@ RAII ("Resource Acquisition Is Initialization") is the simplest, most systematic
14709
14711
{
14710
14712
int* p = new int[12];
14711
14713
// ...
14712
- if (i < 17) throw Bad {"in f()", i};
14714
+ if (i < 17) throw Bad{"in f()", i};
14713
14715
// ...
14714
14716
}
14715
14717
@@ -14721,7 +14723,7 @@ We could carefully release the resource before the throw:
14721
14723
// ...
14722
14724
if (i < 17) {
14723
14725
delete[] p;
14724
- throw Bad {"in f()", i};
14726
+ throw Bad{"in f()", i};
14725
14727
}
14726
14728
// ...
14727
14729
}
@@ -14732,7 +14734,7 @@ This is verbose. In larger code with multiple possible `throw`s explicit release
14732
14734
{
14733
14735
auto p = make_unique<int[]>(12);
14734
14736
// ...
14735
- if (i < 17) throw Bad {"in f()", i};
14737
+ if (i < 17) throw Bad{"in f()", i};
14736
14738
// ...
14737
14739
}
14738
14740
@@ -14990,11 +14992,13 @@ To prevent slicing.
14990
14992
##### Example
14991
14993
14992
14994
void f()
14993
- try {
14994
- // ...
14995
- }
14996
- catch (exception e) { // don't: may slice
14997
- // ...
14995
+ {
14996
+ try {
14997
+ // ...
14998
+ }
14999
+ catch (exception e) { // don't: may slice
15000
+ // ...
15001
+ }
14998
15002
}
14999
15003
15000
15004
Instead, use a reference:
@@ -15592,7 +15596,7 @@ You can
15592
15596
Example:
15593
15597
15594
15598
void f(int* p); // old code: f() does not modify `*p`
15595
- void f(const int* p) { f(const_cast<int*>(p); } // wrapper
15599
+ void f(const int* p) { f(const_cast<int*>(p)) ; } // wrapper
15596
15600
15597
15601
Note that this wrapper solution is a patch that should be used only when the declaration of `f()` cannot be be modified,
15598
15602
e.g. because it is in a library that you cannot modify.
@@ -16296,13 +16300,13 @@ It is a general design rule that even applies to non-templates:
16296
16300
16297
16301
void f(const Minimal& x, const Minimal& y)
16298
16302
{
16299
- if (!(x == y) { /* ... */ } // OK
16303
+ if (!(x == y)) { /* ... */ } // OK
16300
16304
if (x != y) { /* ... */ } // surprise! error
16301
16305
16302
16306
while (!(x < y)) { /* ... */ } // OK
16303
16307
while (x >= y) { /* ... */ } // surprise! error
16304
16308
16305
- x = x + y; // OK
16309
+ x = x + y; // OK
16306
16310
x += y; // surprise! error
16307
16311
}
16308
16312
@@ -16326,14 +16330,14 @@ The rule supports the view that a concept should reflect a (mathematically) cohe
16326
16330
16327
16331
void f(const Convenient& x, const Convenient& y)
16328
16332
{
16329
- if (!(x == y) { /* ... */ } // OK
16333
+ if (!(x == y)) { /* ... */ } // OK
16330
16334
if (x != y) { /* ... */ } // OK
16331
16335
16332
16336
while (!(x < y)) { /* ... */ } // OK
16333
16337
while (x >= y) { /* ... */ } // OK
16334
16338
16335
16339
x = x + y; // OK
16336
- x += y; // OK
16340
+ x += y; // OK
16337
16341
}
16338
16342
16339
16343
It can be a nuisance to define all operators, but not hard.
@@ -18690,7 +18694,7 @@ Don't use C-style strings for operations that require non-trivial memory managem
18690
18694
p[l1] = '.';
18691
18695
strcpy(p + l1 + 1, s2, l2);
18692
18696
p[l1 + l2 + 1] = 0;
18693
- return res ;
18697
+ return p ;
18694
18698
}
18695
18699
18696
18700
Did we get that right?
@@ -19356,7 +19360,7 @@ This technique is a pre-exception technique for RAII-like resource and error han
19356
19360
// ...
19357
19361
int* p = (int*) malloc(n);
19358
19362
// ...
19359
- if (some_ error ) goto_exit;
19363
+ if (some_error ) goto_exit;
19360
19364
// ...
19361
19365
exit:
19362
19366
free(p);
0 commit comments