
Hi, This library seems very interresting. But you say that uncaught_exception_count() has flaws in your code. Can you give any exemple of the cases where your library can be fooled? thanks, ecyrbe 2012/10/2 Evgeny Panasyuk <evgeny.panasyuk@gmail.com>
Hello all,
D language has scope(exit), scope(success) and scope(failure) features - http://dlang.org/statement.**html#ScopeGuardStatement<http://dlang.org/statement.html#ScopeGuardStatement>: "... scope(exit) executes NonEmptyOrScopeBlockStatement when the scope exits normally or when it exits due to exception unwinding. scope(failure) executes NonEmptyOrScopeBlockStatement when the scope exits due to exception unwinding. scope(success) executes NonEmptyOrScopeBlockStatement when the scope exits normally. ..." Andrei Alexandrescu describes some of uses cases for scope(exit), scope(success), scope(failure) at his recent talk : http://channel9.msdn.com/**Events/Lang-NEXT/Lang-NEXT-** 2012/Three-Unlikely-**Successful-Features-of-D<http://channel9.msdn.com/Events/Lang-NEXT/Lang-NEXT-2012/Three-Unlikely-Successful-Features-of-D>
There is Boost.ScopeExit library which emulates D's scope(exit) via BOOST_SCOPE_EXIT macro, but there are no analogues for D's scope(failure) and scope(success). Current alternative for these features is ScopeGuard idiom ( http://en.wikibooks.org/wiki/**More_C%2B%2B_Idioms/Scope_**Guard<http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Scope_Guard>, http://www.drdobbs.com/cpp/**generic-change-the-way-you-** write-excepti/184403758<http://www.drdobbs.com/cpp/generic-change-the-way-you-write-excepti/184403758>).
Boost.ScopeExit library itself suggests to use ScopeGuard - http://www.boost.org/doc/libs/**1_51_0/libs/scope_exit/doc/** html/scope_exit/alternatives.**html#scope_exit.alternatives.** the_d_programming_language<http://www.boost.org/doc/libs/1_51_0/libs/scope_exit/doc/html/scope_exit/alternatives.html#scope_exit.alternatives.the_d_programming_language>: " Boost.ScopeExit is similar to scope(exit) feature built into the D programming language. A curious reader may notice that the library does not implement scope(success) and scope(failure) of the D language. Unfortunately, these are not possible in C++ because failure or success conditions cannot be determined by calling std::uncaught_exception (see Guru of the Week #47 for details about std::uncaught_exception and if it has any good use at all). However, this is not a big problem because these two D's constructs can be expressed in terms of scope(exit) and a bool commit variable (similarly to some examples presented in the Tutorial section). "
I have made small library ( https://github.com/panaseleus/** stack_unwinding#d-style-scope-**guardsactions<https://github.com/panaseleus/stack_unwinding#d-style-scope-guardsactions>) which supplies primitives (class unwinding_indicator, UNWINDING_AWARE_DESTRUCTOR macro) to determining when object destructor is called due to stack-unwinding or due to normal scope leaving. Currently it is implemented on top of platform-specific implementation of uncaught_exception_count function and tested on: {MSVC2005, MSVC2008, MSVC2010, MSVC2012, GCC4.1.2, GCC4.4.6, Clang3.2}x{x32, x64}x{default settings}. uncaught_exception_count is a function similar to std::uncaught_exception from standard library, but instead of boolean result it returns unsigned int showing current count of uncaught exceptions.
Such primitives allow us to implement scope(success) and scope(failure) features in C++. I have made several proof-of-concepts: * https://github.com/panaseleus/**stack_unwinding/blob/master/** examples/scope_actions.cpp<https://github.com/panaseleus/stack_unwinding/blob/master/examples/scope_actions.cpp> * https://github.com/panaseleus/**stack_unwinding/blob/master/** examples/example_from_dlang_**dot_org.cpp<https://github.com/panaseleus/stack_unwinding/blob/master/examples/example_from_dlang_dot_org.cpp> * https://github.com/panaseleus/**stack_unwinding/blob/master/** examples/scope_guard.cpp<https://github.com/panaseleus/stack_unwinding/blob/master/examples/scope_guard.cpp> * https://github.com/panaseleus/**stack_unwinding/blob/master/** examples/boost_scopes.cpp<https://github.com/panaseleus/stack_unwinding/blob/master/examples/boost_scopes.cpp>
boost_scopes.cpp example shows usage of BOOST_SCOPE_FAILURE and BOOST_SCOPE_SUCCESS: try { cout << "Case #1: stack unwinding" << endl; BOOST_SCOPE_EXIT(void) { cout << "exit" << endl; } BOOST_SCOPE_EXIT_END BOOST_SCOPE_FAILURE(void) { cout << "failure" << endl; } BOOST_SCOPE_FAILURE_END BOOST_SCOPE_SUCCESS(void) { cout << "success" << endl; } BOOST_SCOPE_SUCCESS_END throw 1; } catch(int){} { cout << "Case #2: normal exit" << endl; BOOST_SCOPE_EXIT(void) { cout << "exit" << endl; } BOOST_SCOPE_EXIT_END BOOST_SCOPE_FAILURE(void) { cout << "failure" << endl; } BOOST_SCOPE_FAILURE_END BOOST_SCOPE_SUCCESS(void) { cout << "success" << endl; } BOOST_SCOPE_SUCCESS_END } Output is: " Case #1: stack unwinding failure exit Case #2: normal exit success exit "
Currently BOOST_SCOPE_FAILURE and BOOST_SCOPE_SUCCESS are implemented based on boost_1_51_0/boost/scope_exit.**hpp by copy-paste and replace (just for proof-or-concept, of course it is possible solution with much less duplication). Semantically meaningful changes can be viewed as diff at https://github.com/panaseleus/**stack_unwinding/commit/** d5513404323490ea99d9b6b77ff1b8**8f454a4a42<https://github.com/panaseleus/stack_unwinding/commit/d5513404323490ea99d9b6b77ff1b88f454a4a42>
Before posting here, I made posts on several C++ forums, but unfortunately get only a few feedbacks regarding ScopeFailure and ScopeSuccess. What do you think?
Thank you.
P.S. Related discussion: http://lists.boost.org/** Archives/boost/2010/09/171051.**php<http://lists.boost.org/Archives/boost/2010/09/171051.php>
Best Regards, Evgeny Panasyuk
______________________________**_________________ Unsubscribe & other changes: http://lists.boost.org/** mailman/listinfo.cgi/boost<http://lists.boost.org/mailman/listinfo.cgi/boost>