C++ Logo


Advanced search

Re: Some feedback on scope guards

From: Ville Voutilainen <ville.voutilainen_at_[hidden]>
Date: Sun, 16 Apr 2023 18:24:57 +0300
On Sun, 16 Apr 2023 at 14:34, Edward Catmur <ecatmur_at_[hidden]> wrote:
>> I fail to see the problem. It's as if you're suggesting that there's
>> some unknown specification challenge here, but we have the
>> specification
>> you speak of already, in the TS.
> And that specification breaks with coroutines.

I don't see what use it is to repeat that, we all know that.

>> Yes? Neither of those needs other than pointers to them to work. Scope
>> guards are not like them.
>> You found two cases that presumably prove my statement wrong, but
>> (pointers to) those types can
>> be used as subobjects, that works fine, and they work with other
>> library types without problems, since
>> for them it's truly so that you don't need by-value subobjects of them.
>> Try harder.
> And you can take pointers to scope guards. Consider also immovable types like scoped_lock - those won't work with most library components.

I don't want a pointer to a scope guard, I want a reference or a
pointer to a tuple of scope guards.
scoped_lock works just fine with a whole lot of library components, I
can have a tuple of them, an optional of it, a fixed-size
vector of it.

>> >> > Working well can be dealt with by the vendor since these are library types. Wrong - maybe, but this is a scope guard! The name indicates it should be used in a scope.
>> >> Yeah, which does include packaging them any which way I please and
>> >> passing them down to helper functions for further processing,
>> >> or just having a collection-bunch of them in a scope, rather than
>> >> having to have individual objects of the scope guard type directly,
>> >> without
>> >> the possibility to bunch them.
>> > I've never seen code where that would actually be useful.
>> Uhh.. you've never seen code that packages multiple individual objects
>> into a bunch, to pass them as one object to be processed
>> by a helper function? You can't fathom code where you'd take a pack of
>> callbacks and wrap scope guards on top of them, variadically?
> No, since you may as well wrap the lot into a single scope guard.

No, I can't, or rather won't - that then leads into using apply() or
a loop for destruction when none of that is needed
if we don't wreck the design of these wrappers.

>> Well, gee whizz, that's an acceptable cost, compared to preventing the
>> use of scope guards as subobjects, which is not an
>> acceptable cost.
> Using scope_guard outside block scope is a code smell, though it can be justified in some rare cases. Using scope_success or scope_failure outside block scope would not pass code review where I work.

It's not going to be used outside a block scope, it's going to be used
in a scope nested under that scope.

> Meanwhile, using scope_success and scope_failure in coroutine block scope across suspension points is completely natural; the only problem is that it can break. We should not be adding footguns like that to the standard.

There's nothing natural about that; as Jason points out, it's
problematic in the same way as any use of any thread local facility
is, for a coroutine that may be resumed in a different thread.

>> If we have a solution that doesn't do that prevention
>> and solves the coroutine problem, I'm all ears.
> There's Andrey's solution, but the overhead is substantial.

I don't quite follow how that overhead is avoidable just by wrecking
the composability of these types, or at all.

Perhaps we should entertain a separate scope fail/success type that is
coroutine-aware, and leave the TS ones
without that overhead.

Received on 2023-04-16 15:25:11