Boost logo

Boost :

Subject: Re: [boost] Interest in breakable labeled scope emulation?
From: Vicente J. Botet Escriba (vicente.botet_at_[hidden])
Date: 2013-01-16 06:46:17


Le 15/01/13 18:44, Jeffrey Lee Hellrung, Jr. a écrit :
> On Sun, Jan 13, 2013 at 4:30 AM, TONGARI <tongari95_at_[hidden]> wrote:
>
>> Hi all,
>>
>> One of the few things I appreciate in Java is the labeled-break feature.
>> I think C++ would provide it as well in future standard but it seems that
>> there's no even such a proposal.
>>
>> In lack of the language feature, a simple emulation can be used:
>>
>> ---------------------------------------------------
>> #define BOOST_SCOPE(name) \
>> if (const bool LABELED_SCOPE_##name = false){break(name); name:;} else
>>
>>
>> #define break(name) \
>> (void)LABELED_SCOPE_##name; goto name;
>> ---------------------------------------------------
>> Now we can write:
>>
>> BOOST_SCOPE(a)
>> {
>> break(a);
>> cout << "123\n";
>> }
>>
>> The real world usage would reside in nested loop&switch where labeled-break
>> really shines.
>>
>> Thoughts? Sorry if this idea is too simple and somewhat rejected before...
>>
> It's a nice thought but:
> (a) I think the situation where you want to break and/or continue more than
> one loop-level out at a time is rare; and
Agree and its use /could/ be a sign that a refactoring is needed, but
not always.
> (b) in those rare situations, explicitly using gotos and labels (with a
> descriptive name) is reasonably brief and readable;
> so I would be hesitant to adopt this.
>

When we use label/goto directly there is a risk that the user goto to
the label without constructing all the scoped variables, v in this case.

if (cnd3) goto L; // bad as v constructor will not be called.
{
   T v;
   for(;;)
   {
     while (cnd)
     {
       if (cnd2) goto L; // go to [1]
     }
   }
   L: // [1]
   std::cout << v <<std::endl;
}

With named blocks this code will just not compile.

if (cnd3) BOOST_BREAK(L); // compile fail: only allowed from inside the
block.
{
   T v;
   BOOST_NAMED_BLOCK(L)
   for(;;)
   {
     while (cnd)
     {
       if (cnd2) BOOST_BREAK(L); // go to [1]
     }
   }
   // [1]
   std::cout << v <<std::endl;
}

Best,
Vicente


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