pt., 1 gru 2023 o 19:49 Andrey Semashev via Boost
On 12/1/23 20:25, Andrzej Krzemienski via Boost wrote:
Hi All, This is not a review yet. I am just looking at the front page of the docs, and I think the comparison with Boost.ScopeGuard is unfair.
You are comparing C++03 Boost.ScopeGuard with C++11 Boost.Scope. Try comparing it with C++03 Boost.Scope.
Boost.Scope doesn't support C++03.
I'm comparing the libraries using the syntax they provide, regardless of the C++ version, when they both provide equivalent functionality.
Otherwise compare C++11 to C++11, and there Boost.ScopeGuard has a nicer syntax:
int compute() { // Reset variables on return BOOST_SCOPE_EXIT(this_) { this_->x = 0; this_->y = 0; };
return x + y; }
I don't see where the documentation makes BOOST_SCOPE_EXIT_END optional. In every example I can see, BOOST_SCOPE_EXIT is accompanied by BOOST_SCOPE_EXIT_END, C++11 or not. Am I missing something?
Perhaps, you are defining BOOST_SCOPE_EXIT_CONFIG_USE_LAMBDAS and that allows to omit BOOST_SCOPE_EXIT_END? In that case, there is a discussion at the end of this section:
https://lastique.github.io/scope/libs/scope/doc/html/scope/scope_guards.html...
that pertains to your use case, and that makes Boost.ScopeExit very much not equivalent to Boost.Scope.
Thank you. I stand corrected.
Regarding the example with exceptions, nobody would use Boost.ScopeGuard like this. A robust usage is in Boost.ScopeGuard's docs:
void world::add_person(person const& a_person) { bool commit = false;
persons_.push_back(a_person); // (1) direct action // Following block is executed when the enclosing scope exits. BOOST_SCOPE_EXIT(&commit, &persons_) { if(!commit) persons_.pop_back(); // (2) rollback action };
// ... // (3) other operations
commit = true; // (4) disable rollback actions
}
Which is longer, but usable in coroutines. Whereas Boost.Scope's solution is not usable in coroutines.
First, what example are you referring to?
The second (and the last) row of the same table in the Introduction section.
Second, if you mean incompatibility of exception_checker with coroutines then that is already addressed in a note in this section:
https://lastique.github.io/scope/libs/scope/doc/html/scope/scope_guards.html...
If you're using coroutines then just don't use it. Where it is used in library examples, it is implied that coroutines are not used.
I mean something slightly different. Given that in Boost.ScopeExit I need to implement the conditional execution manually, I can do it in two ways. One is: template< typename T > void add_object(T const& arg) { auto it = objects.insert(Object()); auto uncaught_count = boost::core::uncaught_exceptions(); BOOST_SCOPE_EXIT_TPL(this_, it, uncaught_count) { if (uncaught_count != boost::core::uncaught_exceptions()) this_->objects.erase(it); } BOOST_SCOPE_EXIT_END; it->start(arg); } The other is: template< typename T > void add_object(T const& arg) { auto it = objects.insert(Object()); bool active = true; BOOST_SCOPE_EXIT_TPL(this_, it, &active) { if (active) this_->objects.erase(it); } BOOST_SCOPE_EXIT_END; it->start(arg); active = false; } Given these options, I have zero motivation for using the former. The latter one: * is C++11 compatible (boost::uncaught_exceptions doesn't necessarily work for prec++17 compilers) * works correctly in 100% cases rather than in 99% of the cases (I mean the caveats regarding coroutines and fibers) * avoids two calls to a C++ runtime. I think the example with the `active` flag should be used in comparison. And then, if you want to compare apples to apples, you would have to use scope_exit and set_active. Otherwise, I think the comparison should acknowledge that the solution with scope_fail has caveats and is slower. Regards, &rzej;
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost