C++ Logo


Advanced search

Re: [std-proposals] Float the idea | Safer smart pointers

From: Federico Kircheis <federico_at_[hidden]>
Date: Fri, 2 Dec 2022 23:59:18 +0100
On 02/12/2022 19.21, Arthur O'Dwyer via Std-Proposals wrote:
> On Fri, Dec 2, 2022 at 12:59 PM Francesco Scappatura via Std-Proposals
> <std-proposals_at_[hidden] <mailto:std-proposals_at_[hidden]>>
> wrote:
> With C++ smart pointers there is a lot of space for unexperienced
> programmer to run into double free and doing things that are
> semantically wrong.
> Some examples:
> -You can create a raw pointer and initialize two different
> unique_pointer. (double free).
> -You can create a raw pointer and initialize two different
> shared_pointer. (double free + wrong count).
> -You can bind a raw pointer to both a unique and a shared_pointer.
> (double free and semantically incorrect).
> None of these have been a practical problem since C++14, which
> introduced `std::make_unique`. (`std::make_shared` has always existed.)
> To heap-allocate something managed by a smart pointer, all you have to do is
> auto p = std::make_shared<Widget>(1,2,3);
> auto q = std::make_shared<Widget>(4,5,6);
> To point `p` at an existing heap-allocation:
> p = std::move(q);
> To point it at a new heap-allocation:
> p = std::make_shared<Widget>(7,8,9);
> My mantra for using smart pointers to manage /*ownership*/
> of heap-allocated objects is "Don't touch raw pointers with your hands."
> HTH,
> Arthur
> P.S. — Admittedly you can still get into trouble by using some of the
> arcane named methods of the smart-pointer objects themselves:
> p.release(); // memory leak
> q.reset(r.get()); // double-free bug
> But it's easy to grep your codebase for `.reset(` and `.release(`, just
> like you already grep for `reinterpret_cast` or `new ` or `volatile` or
> whatever other code smells you prefer to prohibit.

Note that instead of grepping, you can in certain cases use your
compiler (at least gcc and clang), with the poison pragma

I've used this technique it successfully multiple times, granted most of
the time when working with a C API (no overloads, symbol in global
namespace, ...), as the pragma works on tokens and does not take
overloads into account, but nonetheless, it helped to avoid a lot of
issues (mostly resource leaks) at compile-time.


Received on 2022-12-02 22:59:30