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
Merge rules R.12 and R.13; explain about RAII factories.
R.12 and R.13 were both written for a C-style world where the idea was
to get raw resource pointers and then quickly "give" them to RAII types.
The modern C++ approach is actually to use RAII types exclusively,
and never handle raw resource pointers even for an instant. R.13 was
kind of getting there, in that it knew `make_shared` existed; but we
can strengthen the rule by just saying "Please, use `make_shared`."
"Raw pointers are like raw meat: don't touch them with your hands."
Also update for C++17: it's no longer true that `shared_ptr<T>(new T())`
can ever cause a leak due to interleaved evaluations.
But it's still a nasty habit. Use `make_shared`.
@@ -9365,73 +9364,75 @@ If you have a naked `new`, you probably need a naked `delete` somewhere, so you
9365
9364
9366
9365
(Simple) Warn on any explicit use of `new` and `delete`. Suggest using `make_unique` instead.
9367
9366
9368
-
### <a name="Rr-immediate-alloc"></a>R.12: Immediately give the result of an explicit resource allocation to a manager object
9367
+
### <a name="Rr-immediate-alloc"></a>R.12: Instead of manual resource allocation, use factory functions that return RAII objects
9369
9368
9370
9369
##### Reason
9371
9370
9372
9371
If you don't, an exception or a return may lead to a leak.
9373
9372
9374
-
##### Example, bad
9373
+
##### Example
9375
9374
9376
-
void f(const string& name)
9375
+
void bad(const char *name)
9377
9376
{
9378
-
FILE* f = fopen(name, "r"); // open the file
9379
-
vector<char> buf(1024);
9380
-
auto _ = finally([f] { fclose(f); }); // remember to close the file
9377
+
FILE *f = fopen(name, "r");
9378
+
std::vector<char> buf(1024);
9381
9379
// ...
9382
9380
}
9383
9381
9384
-
The allocation of `buf` may fail and leak the file handle.
9385
-
9386
-
##### Example
9382
+
If `buf`'s constructor throws, then `FILE *f` will not be `fclose`d — a resource leak.
9383
+
Prefer to use an RAII object such as `std::ifstream`.
9387
9384
9388
-
void f(const string& name)
9385
+
void good(const char *name)
9389
9386
{
9390
-
ifstream f{name}; // open the file
9391
-
vector<char> buf(1024);
9387
+
std::ifstream myfile(name);
9388
+
std::vector<char> buf(1024);
9392
9389
// ...
9393
9390
}
9394
9391
9395
-
The use of the file handle (in `ifstream`) is simple, efficient, and safe.
9396
-
9397
-
##### Enforcement
9398
-
9399
-
* Flag explicit allocations used to initialize pointers (problem: how many direct resource allocations can we recognize?)
9400
-
9401
-
### <a name="Rr-single-alloc"></a>R.13: Perform at most one explicit resource allocation in a single expression statement
9402
-
9403
-
##### Reason
9404
-
9405
-
If you perform two explicit resource allocations in one statement, you could leak resources because the order of evaluation of many subexpressions, including function arguments, is unspecified.
0 commit comments