12

This is what I would like to do:

{
    ...
    if(condition)
        break;
    ...
}

This works for a loop. I would like something similar for a simple block of code. Is it possible?
Am I forced to use a "goto"?


I think such an extension of the break statement would have been a useful addition to C++11...

Pietro
  • 12,086
  • 26
  • 100
  • 193
  • 4
    ...or to refactor your code with more atomic functions. – Adriano Repetti Sep 07 '12 at 08:42
  • 1
    If you would post more code, we could suggest a better solution than using goto or other tricks. – Steed Sep 07 '12 at 08:43
  • If you're actually considering goto, you need to refactor. – derpface Sep 07 '12 at 09:41
  • 5
    put it in a function, and return. When people say "don't use goto", they don't mean "do the same thing you'd have done if you could use goto, but just rename the keyword to something else". They mean "restructure your code so you don't *need* to use goto" – jalf Sep 07 '12 at 10:00

8 Answers8

8

How about

do
{
    ...
    if(condition)
        break;
    ...
}
while (0);

I don't particularly like this style but I've seen it before. If refactoring is out of the question (could be for a massive block that can break a lot of stuff if changed), this is an option.

Luchian Grigore
  • 253,575
  • 64
  • 457
  • 625
  • 8
    How is that better than a `goto` ? – MSalters Sep 07 '12 at 08:48
  • 4
    @LuchianGrigore I don't know, it works but in this case the trick is more confusing than a goto. At least with goto you know what happens and why, with do/while (I imagine his code isn't short here) when someone reads the code first thinks about a loop then he must understand the reason of a while(0)... – Adriano Repetti Sep 07 '12 at 09:42
  • 2
    A goto would be much clearer than this rather cryptic contrivance, and though I can't speak for the great man himself, I'm pretty sure that Dijkstra would prefer it, too. Although he'd surely prefer a solution that avoided either :) – SSJ_GZ Sep 07 '12 at 09:54
6

Here's one way:

switch(0) {
default:
    /* code */
    if (cond) break;
    /* code */
}

(please never do this)

jleahy
  • 16,149
  • 6
  • 47
  • 66
  • great idea, why not, what could possible go wrong... until this one, my best answer would be `for (int i=0;!i++;) {...}` but switch-case do not involve variable and seems better. – MetNP Jan 22 '18 at 03:56
6

In C++11 the best way to achieve this is use a anonymous lambda function and replacing break with return

[&](){
    ...
    if(condition)
        return;
    ...
 }();

Note that [&] captures all variables by reference, if you don't use any just replace it with []

Edwin Rodríguez
  • 1,229
  • 10
  • 19
  • 2
    Nice. However that `return` is misleading, because what the code is intended to do is effectively a `break`. – Pietro Dec 17 '15 at 14:20
  • @Pietro You right!. Moreover, the main limitation of this method is that it can't `return` in the same way that a block does. If you need that your block to return then the `do while` solution is the right one. – Edwin Rodríguez Dec 17 '15 at 14:23
5

This one:

{
    // ...

    if (!condition)
    {
        // ...
    }
}

This will avoid goto to jump out of a block of code.

Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084
Charan Pai
  • 2,288
  • 5
  • 32
  • 44
  • 2
    I agree with you, but in my case most of the code would have to be moved inside a further if block. Stylistically it would be better to be able to jump out of the block if the condition is true. – Pietro Sep 07 '12 at 09:01
  • ya this is simple way of doing and more importent is understandability of your code than to be stylish. To be stylish reffer Luchian Grigore's code it has no goto statement. :) – Charan Pai Sep 07 '12 at 09:38
3

Here just some additional possibilities:

for(..)
{
    continue;//next loop iteration
}

void mymethod()
{
    ...
    return;
    ...
}

Probably you should create sub-methods for the problematic block of code were you wanted to use goto and leave the block of code by the usage of return.

Alex
  • 1,602
  • 20
  • 33
  • These cases aren't answering the question because they aren't simple blocks of code – Edwin Rodríguez Dec 16 '15 at 22:18
  • Sometimes the question itself is part of the problem. Re-factoring the code in order to use sub-routines, instead of leaving a code-block probably would be the cleanest solution. So there would be no need any more to leave a specific code-block. – Alex Dec 18 '15 at 10:11
1

I'm afraid I'm unleashing the wrath of a coding god against me right now, but this nice nasty macro could help people do this easier than before (based on @jleahy's answer):

//example use:
// { __breakable__
//    ...
//    if (condition)
//        break;
//    ...
//    if (condition2)
//        break;
//    ...
// }
//WARNING: use only with a standalone block. To make if, try or catch block
//         breakable use double braces
//         if (cond) {{ __breakable__ ... }}
//         try {{ __breakable__ ... }} catch (...) {{ __breakable__ ... }}
#define __breakable__ }switch(0){default:
  • This solution looks the worst under the implementation point of view (becuse of the preprocessor trick), but it seems the best under an expression of intent angle. – Pietro Dec 11 '19 at 23:12
0

I settled with using:

if (1) {
   if (1) goto End;
   ...
   ...
End:
   ;
}
Necktwi
  • 2,483
  • 7
  • 39
  • 62
-3

"I would like something similar for a simple block of code."

Use return after a condition is met, and return control back to the caller.

void MyWorkerClass::doWork(Item & workItem) {
    // ...
    if(noMoreWorkToDo)
        return;
    // ...
}
mrflash818
  • 930
  • 13
  • 24