
Andrey, thanks for the review.
- The usage of Boost.Typeof may be discouraging because of need to register user-defined types. This might be no problem for types that indeed are defined by the user, but there are cases when they are not (OS API, third party libraries, etc.). And interaction with such APIs in a transaction-like manner is a quite probable place to employ ScopeExit.
The library is oriented towards C++0x with decltype proposal accepted ;-) I realise typeof emulation mode is discouraging and I tried to come up with a good syntax for explicit types as you suggest below.
- The scope-exit block arguments are taken by reference. I consider this as a drawback because it is most often desirable to fix the environment state at the point where the guard is created. The most frequent and, in majority, the only exception to this is the "commit/dispose" flag. Playing otherwise may lead to subtle errors. Consider the following examples:
...
These are just illustrations, I understand that I could have created copies of the needed variables on the stack. But I think this should be the default behavior of the library, and passing by reference should be an available option.
These are good examples. Would you accept the syntax suggested in my other reply to you message if it's ever possible in C++ BOOST_SCOPE_EXIT( byref(r) byval(v) ) ? or, if some C++ contruct X exists such that 'X id' and 'X &id' are both valid C++ and both can be transformed to typeof(id), then I could write the ScopeExit macro like this BOOST_SCOPE_EXIT( (&r)(v) ) .
That said, I'd like to vote to add a new set of macros that would allow: - Explicitly state the scope-exit argument types - Explicitly state if arguments should be bound by reference or not
These macros should not depend on Boost.Typeof in any way (not even #include it). The syntax might involve PP tuples like this:
BOOST_SCOPE_EXIT_BEGIN( (int, i)(BOOST_TYPEOF(x + y), j)(bool&, commit)) { } BOOST_SCOPE_EXIT_END Variables i and j are bound by value and commit - by reference in the snippet above.
Comma between int and i is unnatural but it's not possible to extract i out of '(int i)' or '(int& i)'.
- Configuration page. It says that BOOST_SCOPE_EXIT_FASTER_IMPL is not supported which makes me feel like I'm discouraged from using it. May be it shouldn't be documented then?
It probably shouldn't. My intension was to advertise this trick so that someone smarter than me could supply a patch for other platforms/compilers.
- If BOOST_SCOPE_EXIT_FASTER_IMPL optimizes something, it would be nice to see performance comparisons to the non-optimized version. - Anyway, performance section would be appreciated. I'd like to see the speed impact comparing to other alternatives you listed in the docs. In particular, I'd like to see the difference depending on the scope-exit block arguments number. I can see some performance notes on the Implementation page, but there are no experimental data.
I don't want to mislead people. There are so many processors, compilers and compilation flags that I suspect my performance comparison may give opposite results on different computers. I don't think performance depends on number of arguments unless you pass 50-100. It's like measuring performance of function calls with a different number of arguments. -- Alexander