-2

I am used to avoid goto statement in all cost , because it is not adviced c++ , i still need sometimes to jump to the buttom of the code and exit the process when an error occur like this :

if ( cond1 )
{
   if (cond2)
   {
     do_something();
     return; // note the return
   }else
   {
      goto error_oc;
   }
}else
{
   if() ...
    return;
}

// should never be eached
error_oc: 
error_message();
exit(1);

now suppose the error message is a complex one , and suppose we didnt put it in a function like that , so we will have to write the complex msg code twice , now a better solution :

std::function <void(void)> error_lambda = [] (int code) {
   // complex error msg here with captured variiables maybe
 exit(code);
}    
if ( cond1 )
{
  if (cond2)
  {
    do_something();
    return; // note the return
  }else
  {
    error_lambda(1);
  }
}else
{
   if() ...
    return;
}

// should never be eached
error_lambda(2);

what are the pros and cons of the solution vs the goto solution ?

Andreas
  • 5,086
  • 3
  • 16
  • 36
Dhia Hassen
  • 508
  • 4
  • 20
  • 4
    *"How good is my solution ?"* has no possible answer. See [ask] – Passer By Mar 17 '18 at 16:07
  • In the first you mix the "single return only idiom" with multiple returns. It makes your code hard to read and follow (besides the formatting and inconsistent indentation also doing that). – Some programmer dude Mar 17 '18 at 16:14
  • In the 1st example just remove `goto error_oc;` only - it will have the same effect. – Richard Critten Mar 17 '18 at 16:15
  • 3
    Whatever else you do, there is no reason to store your lambda in a `std::function`. That introduces an overhead for no benefit. Just use `auto`. You only need `std::function` if the functor type you want to store is determined at runtime. Or if you want something like an array of functors of various types, and you want to decide which one to call by an index into that array. – Benjamin Lindley Mar 17 '18 at 16:19
  • 3
    The C++ style is not to use neither goto nor lambda but to use exceptions and catch it outside. – freakish Mar 17 '18 at 16:21
  • 2
    Just throw an exception, the rest will happen on its own. Neither of your two solutions are actually readable to me, but that might be because the formatting is messed up. – Ulrich Eckhardt Mar 17 '18 at 16:22

1 Answers1

2

First of all your two codes are equivalent only because you use exit() call. Otherwise the inner else block would call error_lambda once and then again after leaving if statement. This already shows that the behaviour havily depends on error_lambda itself which IMO makes the code hard to read and maintain.

On the other hand there are good reasons not to use goto ever. It's just evil. Forget you heard about it. During my entire life I only used goto once and I'm still ashamed of this (I was too lazy to restructure the code properly).

So here's the deal. You want to interrupt your normal code execution on error. But neither goto nor lambda is maintainable. So are we doomed? But hey, you are using C++. So why don't you use the mechanism specifically designed to handle this case: exceptions? You can create your own, custom one (add any custom data you need), throw it and then catch it outside and log it or do whatever you need to do with it.

freakish
  • 54,167
  • 9
  • 132
  • 169