Allow multiple calls with shared pointers arguments (not being a reference parameter) for rule R.21
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?
I don't know why the rule is written in terms of Shared_pointer& as a reference argument (and it should be shared_ptr).
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.
Editors call: We agree the & should be removed. Thanks!