Replies: 2 comments 3 replies
-
Note that the no-op deleter can be the same for all types |
Beta Was this translation helpful? Give feedback.
-
Maybe a wild take on this, but don't you think it is worth breaking backwards compat in turn to simplify lifetime management? This should be done with a clear upgrade path described for users which want to go forward. From my understanding the "maybe owning" semantics stems from the issue that the objects are not reference counted in MFEM, hence it is not a-priori clear which object has to live for how long a priori. Hence there are flags introduced to manage this lifetime information manually. Keeping the product operator you have at top as an example, with shared pointer this problem would not occur, as the pointer itself manages its lifetime (by reference counting). Furthermore, for non-owning semantics we have https://en.cppreference.com/w/cpp/memory/weak_ptr |
Beta Was this translation helpful? Give feedback.
-
There has been an ongoing discussion on further incorporating smart pointers (in particular, shared/reference-counted pointers) in MFEM. In order to be backwards compatible, it seems required to model "maybe owning" semantics — the smart pointer may own the pointed-to object, or it may not, and this depends on runtime information. Perhaps the simplest example is something like
ProductOperator
, whose declaration is given here:mfem/linalg/operator.hpp
Lines 892 to 909 in 899a96b
Depending on the boolean flags
ownA
andownB
, the resultingProductOperator
may or may not own the pointed-to operators. The current implementation has incorrect copy/move semantics, which may cause issues in otherwise well-formed code (e.g. storingProductOperator
in a standard container), and the manual management of ownership rules may cause subtle bugs/memory leaks (see e.g. #4613 from as recently as today).We can modify
ProductOperator
(and similar classes) in a fully backwards-compatible way using smart pointers that model "maybe owning" semantics. We have discussed two approaches to achieve this:std::shared_ptr
. An "owning"shared_ptr
is created as usual, whereas a "non-owning"shared_ptr
is created with a no-op deleter, e.g.[](T*){}
. Convenience functions can be used to make specifying the ownership convenient and explicit.shared_ptr
.shared_ptr
(it was referred to in the meeting as an "abuse") and it may confuse users. We can't provide our own documentation for this class. An existingshared_ptr
can't be easily queried about whether it is owning or not.Handle<T>
) that is built on top ofshared_ptr
.13 votes ·
Beta Was this translation helpful? Give feedback.
All reactions