
On 3-Apr-07, at 6:52 PM, Alexander Nasonov wrote:
Andrey Semashev wrote:
What if something like that:
BOOST_SCOPE_EXIT // line 1 /* Expands to: struct _scope_guard_class_line1 { ~_scope_guard_class_line1() { */ { // scope(exit) code } BOOST_SCOPE_EXIT_END((hello)(world)); // line 5 /* Expands to: }
std::string& hello; std::string& world; } _scope_guard_line5 = { hello, world }; */
While the variable list is now in the end, no ids needed at all.
I considered it too but I thought it could scare people.
So, we have
1. BOOST_SCOPE_EXIT { // ... } BOOST_SCOPE_EXIT_END( (hello)(world) )
or, putting the code as a parameter to the macro: BOOST_SCOPE_EXIT( (hello)(world), { // ... } );
2. BOOST_SCOPE_EXIT(id, (hello)(world) ) { // ... } BOOST_SCOPE_EXIT_END(id)
3. with global variable BOOST_SCOPE_EXIT( (hello)(world) ) { // ... } BOOST_SCOPE_EXIT_END
What about using a static variable instead? // User code //BOOST_SCOPE_EXIT( (hello)(world) ) // line 1 /* Expands to: */ static struct args_line1_t { std::string &hello, &world; } args_line1 = { hello, world }; struct scope_exit_line1 { ~scope_exit_line1() { struct args_line1_t* p = (struct args_line1_t*)&args_line1; doit(p->hello, p->world); } static void doit(std::string& hello, std::string& world) /**/ { // scope(exit) code } /**/ //BOOST_SCOPE_EXIT_END // line 5 /**/ } scope_exit_line5; /**/ If the variables are on the stack (or inside thread storage), it should be thread-safe, right? Is the use of __LINE__ correct? I can't think of a way to break it, which in no way means it's perfect... Hans Post-Scriptum:
Why do you need that library and is it absolutely necessary? Because I saw so much exception unaware code. I don't see any case of valid exceptions in the use of this library. Sorry, I don't understand this statement.
Simply that BOOST_SCOPE_EXIT( ... ) { throw XXX; } Is invalid by definition. So I don't know why you'd need to be exception aware - or exception whatever in this case. We don't call any external variables and use references, therefore I don't see a case where our own code might throw an exception outside of the client-code. If you're talking about the fact that you need to get an unknown typename into a local-class (how to know that hello and world are std::string, for example), then the typeof dependency is well justified. Otherwise, I still fail to see why it is needed.
I even considered something like this in the past:
{ BOOST_SCOPE_EXIT( (hello)(world) { // code }} id;
It may seem strange but not to people familiar with ruby blocks:
{ |hello,world| // code }