Boost logo

Boost :

Subject: Re: [boost] [Utility] intuitive scoping with BOOST_WITH
From: Marcel Ebmer (marcel_at_[hidden])
Date: 2015-08-08 18:38:13


Thank you Andrey,

On 08/07/2015 11:07 AM, Andrey Semashev wrote:
> On 07.08.2015 03:09, Marcel Ebmer wrote:
>> ...
>> https://github.com/maysl/BOOST_WITH
>
> I don't think this utility gives much compared to the naive macro-less
> solution:
>
> f() {
> {
> Lock lock{the_mutex});
> do_something();
> do_other_thing();
> }
> do_something_without_a_lock();
> }
Your example nicely shows two things I want to overcome with 'with'
1) You define a variable that you never use
2) The solution, using an explicit scope, is not very expressive

>
> Also, your macro requires the type to be movable. This seems like a
> rather strong requirement. For instance, it won't work with
> lock_guard. If you really want to improve it you might want to use
> 'for' statement instead of 'if', something along these lines:
>
I simply did not find a way to implement this for non-movable types
(like lock_guard). Naturally, if there is one, I would be delighted!

> template< typename T >
> struct with_value
> {
> T value;
> bool guard;
> };
>
> #define BOOST_WITH(x)\
> for (with_value<decltype(x)> w{x, true}; w.guard; w.guard=false)
>
The 'for' loop solution has a serious flaw in that you change the
meaning of 'break' and 'continue':

while (true)
     BOOST_WITH(whatever) // for(...)
         if (something)
             break; // breaks the single-pass for loop

> There is another limitation that is not so easy to lift - you cannot
> access the guard value from within the scope. For instance, you cannot
> use the lock to block on a condition variable.
>
This limitation is 100% intentional. When I need access to the scoped
variable, BOOST_WITH is not the way to go. The macro (or the
hypothetical with-statement) is meant for the not so uncommon case where
you do not care about the variable name. In fact, I originally had the
idea because I had discovered this bug:

void f() {
     std::lock_guard<std::mutex>{the_mutex}; // name missing, only a temporary
     do_something(); // the_mutex not locked
}

Marcel


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk