Re: [boost] [scope] scope_fail is unimplementable

niedz., 9 kwi 2023 o 03:11 Andrey Semashev via Boost
On 4/9/23 03:20, Andrzej Krzemienski wrote:
Well, in my experience, the scope fail/success is exclusively about exceptions, so I will still focus on exceptions. Here is a small benchmark comparing the deactivation-based mechanism of a scope_guard with uncaught_exception-based mechanism of
scope_fail.
The former performed like 36 times faster, as it doesn't have to perform the calls to the runtime.
Sorry. Forgot the link. Here it is: https://quick-bench.com/q/0InBohGrnD5-soYT_GwvaCEaG74 https://quick-bench.com/q/0InBohGrnD5-soYT_GwvaCEaG74
The thing with manually dismissing (or activating) the scope guard before leaving the scope diminishes the usefulness of the scope guard. The first and foremost reason to use a scope guard is to automate execution of the action upon exiting the scope. If you now have to manually ensure this at every point where you might leave the function, what's the point of using it in the first place?
To "automate" is just one goal. A more modest one is to "make it manageable". Like in the case where you want to push_back into two vectors in a transactional-like fashion: vec1.push_back(Connection{params}); scope_guard pushGuard {[&]{ vec1.pop_back(); }} vec2.push_back(Storage{params}); pushGuard.deactivate(); The problem is contained, so I do not mind the call to deactivate(). But without the scope_guard, I would have to define my own class that does a pop-back in the destructor.
Yes, you can manually (de)activate the guard in small and contained cases, but in general I would very much prefer it to work automatically. Otherwise, it quickly becomes a maintenance nightmare that it was supposed to fix.
True. Therefore in my code I would contain the code that requires a guard. (In general, I prefer RAII.) But even contained cases need a scope guard. So, the trade-off is this: scope_fail: - requires no manual deactivate scope_guard with deactivate(): - works uniformly and unsurprisingly in all contexts, including coroutines - is fast. I would recommend that this trade-off is documented. Regards, &rzej;
Regarding failure conditions other than exceptions, the problem with coroutines may still appear if a thread-local storage is used, such as errno.
errno is volatile (not in core C++ terms but in terms of it changing its value in various non-obvious ways), so you would normally read its value into a local variable immediately after a syscall for testing before returning. It is that local variable that you check in the scope guard, not errno itself.
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

On 4/14/23 09:39, Andrzej Krzemienski wrote:
niedz., 9 kwi 2023 o 03:11 Andrey Semashev via Boost
mailto:boost@lists.boost.org> napisał(a): Yes, you can manually (de)activate the guard in small and contained cases, but in general I would very much prefer it to work automatically. Otherwise, it quickly becomes a maintenance nightmare that it was supposed to fix.
True. Therefore in my code I would contain the code that requires a guard. (In general, I prefer RAII.) But even contained cases need a scope guard.
So, the trade-off is this: scope_fail: - requires no manual deactivate
scope_guard with deactivate(): - works uniformly and unsurprisingly in all contexts, including coroutines - is fast.
I would recommend that this trade-off is documented.
Yes, that makes sense. I will update the docs.

On 4/14/23 13:00, Andrey Semashev wrote:
On 4/14/23 09:39, Andrzej Krzemienski wrote:
niedz., 9 kwi 2023 o 03:11 Andrey Semashev via Boost
mailto:boost@lists.boost.org> napisał(a): Yes, you can manually (de)activate the guard in small and contained cases, but in general I would very much prefer it to work automatically. Otherwise, it quickly becomes a maintenance nightmare that it was supposed to fix.
True. Therefore in my code I would contain the code that requires a guard. (In general, I prefer RAII.) But even contained cases need a scope guard.
So, the trade-off is this: scope_fail: - requires no manual deactivate
scope_guard with deactivate(): - works uniformly and unsurprisingly in all contexts, including coroutines - is fast.
I would recommend that this trade-off is documented.
Yes, that makes sense. I will update the docs.
Done. I have added a comparison of scope_fail and scope_exit and a discussion of pros and cons of each.
participants (2)
-
Andrey Semashev
-
Andrzej Krzemienski