On 30/07/2019 03:34, Zach Laine wrote:
I've compiled the results of the reviews of out_ptr during its recent review. Many thanks for managing the review process.
Now, on to exceptions in out_ptr's types' dtors. I heard a lot of discussion about this during the review. To me, concerns about what happens when an out_ptr or an inout_ptr throws in its dtor misses the point entirely, because it is concerned with fixing corner cases we should not even care to support.
I don't think I can agree with that. shared_ptr's reset (or some other kind of smart pointer) is absolutely allowed to throw, and since by design this would be called in out_ptr's destructor, this case needs to be considered.
Instead of worrying about the semantics of exceptions in those kinds of situations, we should instead be asking why we want to support user code like this:
... } catch { create_foo(in_out_ptr(my_shared_ptr_to_a_foo)); ... }
That's not legal anyway, since in_out_ptr is incompatible with shared_ptr, as it lacks the ability to release() a uniquely owned raw pointer. Consider instead (with no exceptions already in flight): create_foo(out_ptr(a), out_ptr(b)); The out_ptr destructors are executed in unspecified order. One of them might throw before the other one, and the other one might also throw (but even if it doesn't, is it safe from leaking memory? What if the caller doesn't want std::terminate to be called?).
In other words, the question should have been "Why support anything other than nothrow-constructible RAII types like unque_ptr?" Note that I find this argument compelling for the WG21-facing version of this work too.
I find this argument compelling as well, but presumably one of the original goals was to interoperate with existing smart pointer types such as CComPtr or RefPtr. Perhaps that does come at too high a price though. While the lambda-based syntax that I proposed is definitely not as tidy as CComPtr's operator& or OutPtr's current syntax, it does resolve a lot of these safety concerns (all of them, AFAIK). It's unfortunate that C++ lacks a more compact lambda expression syntax.