C++ Logo

std-discussion

Advanced search

Re: Some feedback on scope guards

From: Edward Catmur <ecatmur_at_[hidden]>
Date: Thu, 13 Apr 2023 21:12:34 -0300
On Thu, 13 Apr 2023, 21:08 Jason McKesson via Std-Discussion, <
std-discussion_at_[hidden]> wrote:

> On Thu, Apr 13, 2023 at 7:22 PM Edward Catmur via Std-Discussion
> <std-discussion_at_[hidden]> wrote:
> >
> >
> >
> > On Thu, 13 Apr 2023 at 19:56, Marcin Jaczewski <
> marcinjaczewski86_at_[hidden]> wrote:
> >>
> >> pt., 14 kwi 2023 o 00:16 Ville Voutilainen via Std-Discussion
> >> <std-discussion_at_[hidden]> napisaƂ(a):
> >> >
> >> > On Fri, 14 Apr 2023 at 01:12, Edward Catmur <ecatmur_at_[hidden]>
> wrote:
> >> >
> >> > >> > The thing is, it is possible for scope guard destructors to
> detect how they were called. We just have to give up composability, which
> honestly doesn't seem like that much of an issue - why would you want to
> put a scope guard inside another object or in dynamic storage?
> >> > >>
> >> > >> To give RAII semantics to types that don't have them internally,
> >> > >> without having to write holder types. If that's the price of
> getting
> >> > >> coroutines to work, to lose the ability to do that, then you can
> burn
> >> > >> coroutines for all I care.
> >> > >
> >> > >
> >> > > If it's for RAII, then plain scope_guard should be fine (even if a
> bit misused; a class type is not a scope). scope_success and scope_failure
> would not make much sense as data members unless you're writing another
> success/failure scope guard class (what I meant by composability).
> >> >
> >> > That I can probably live with.
> >>
> >> But why can't it compose? We need to propagate compile time
> >> information. We already have propagation when we use `const` methods.
> >> I previously suggest using `requires` for this but it could be a new
> >> contextual keyword like:
> >>
> >> ```
> >> //Foo.h
> >> class Foo
> >> {
> >> X x;
> >> ~Foo() scope_fail;
> >> ~Foo() scope_success;
> >> };
> >> ```
> >> As this keyword is part of a signature, in other compilation units we
> >> still know what context it is.
> >> ```
> >> //Foo.cpp
> >> Foo::~Foo() scope_fail
> >> {
> >> };
> >> ```
> >> Now `X` could calls `X::~X() scope_fail;` or if it does not exist then
> >> `X::~X()`.
> >> Only problem is that you need to propagate "scope" for the whole
> hierarchy,
> >> the same as we need to propagate `const`.
> >> Interesting case would be `std::optional<Foo>` (or other containers)
> >> but this could be handed by
> >> calling the destructor directly like `x.~Foo() scope_fail;`.
> >>
> >> This would need update of std types but it should not be breaking
> changes
> >> as a new specialid destructor could be behind `requires` and new type
> trait.
> >
> >
> > Sure. But that would be a lot of work (for the Committee); it would
> require getting it through multiple working groups. If instead we just
> specify that scope_success and scope_failure are only guaranteed to work as
> complete automatic objects (but are guaranteed to work in coroutine scope),
> leaving the details up to the vendors, that can be done through Library
> Evolution. We can always standardize the technique itself later, but don't
> need to hold things up now. (I'd be inclined to add a parameter to the
> destructor, since that could be passed along via `delete`, `destroy_at`
> etc.)
>
> I really don't like the idea of picking functionality based on what is
> easiest to get through the committee instead of what is best for the
> language. If it's important enough to go into the standard, then it's
> important to do it in a reasonable way even if it's a bit harder. And
> if it's not important enough to be worth the effort, then maybe we
> shouldn't bother.
>

The functionality would be exactly the same. The difference would be
whether anyone other than the standard library would be able to implement
it.

You know, like we had in vector for 10+ years. Or like we have now with
node_handle.

>

Received on 2023-04-14 00:12:49