CppCoreGuidelines icon indicating copy to clipboard operation
CppCoreGuidelines copied to clipboard

Allow multiple calls with shared pointers arguments (not being a reference parameter) for rule R.21

Open jansen-tiobe opened this issue 1 year ago • 2 comments

I would like to thank Danny Havenith for bringing up this example and suggesting this improvement.

Rule R.21 ("Prefer unique_ptr over shared_ptr unless you need to share ownership") has enforcement:

(Simple) Warn if a function uses a Shared_pointer with an object allocated within the function, but never returns the Shared_pointer or passes it to a function requiring a Shared_pointer&. Suggest using unique_ptr instead.

Now consider the following code:

void Registry::add( shared_pointer< Participant> w);

void f( Registry &r1, Registry &r2)
{
    const auto p = make_shared<Participant>();
    r1.add( p);
    r2.add( p);
}

According to the enforcement this code will be flagged, but it is not possible to use a unique_ptr in this case because the pointer is shared between 2 function calls.

Hence, I suggest to extend the enforcement as follows:

_(Simple) Warn if a function uses a Shared_pointer with an object allocated within the function, but:

  • never returns the Shared_pointer and
  • never passes it to a function requiring a Shared_pointer& and
  • does not pass it to a function as a Shared_pointer argument (by value or reference) more than once.

Suggest using unique_ptr instead._

What are your thoughts? Should I just create a pull request for this change?

jansen-tiobe avatar Oct 14 '24 21:10 jansen-tiobe

I don't know why the rule is written in terms of Shared_pointer& as a reference argument (and it should be shared_ptr).

jwakely avatar Oct 14 '24 22:10 jwakely

Ah, because if the function takes shared_ptr<Participant> by value then you could pass a unique_ptr as an rvalue, as foo(std::move(p))

But I think your proposed change is still too restrictive. Any use of the shared_ptr after the first call to add requires that it hasn't been moved from. This couldn't be a unique_ptr:

void f( Registry& r1)
{
    const auto p = make_shared<Participant>();
    r1.add(p);
    foo(*p);
}

This would still get a warning with your suggested rewrite.

jwakely avatar Oct 14 '24 22:10 jwakely

Editors call: We agree the & should be removed. Thanks!

hsutter avatar Oct 24 '24 18:10 hsutter