Here are the only two ways I know that roughly makes sense:
for (){
for (){
if (found the target) goto cont;
}
}
cont:;
I've seen people strongly recommending against using goto
, but I feel like this is a pretty proper way of using it.
bool exit=false;
for (){
for (){
if (found the target){
exit=true;
break;
}
}
if (exit) break;
}
I write a bit more code this way.
What would you say to be the proper way to do this?
CodePudding user response:
You can add a layer of abstraction. If this is a loop that will be used in multiple places, then wrap it in a function like
auto do_stuff(params_t params)
{
for (...){
for (...){
if (found_the_target) return something;
}
}
}
If this is a one off, then you can create a lambda on the fly like
auto thing_i_wanted_to_know = [&]{ for(...){
for(...){
if (found_the_target) return something;
}
}
}();
CodePudding user response:
Just change your nested loops the following way
bool exit=false;
for ( ; !exit; ){
for ( ; !exit; ){
if (found the target){
exit=true;
}
}
}
Usually the inner for loop can be rewritten either like while or do-while loop avoiding using the break
statement that makes the code more clear.
CodePudding user response:
I consider this to be a valid use of goto
, but I myself use flags for this.
As an experiment, I've also ported Java's named loops to C , using macros.
Usage:
for (int i = 0; i < 10; i ) LOOP_NAME(foo)
{
for (int j = 0; j < 10; j )
{
if (i == 5 && j == 5)
break(foo);
}
}
#define LOOP_NAME(name) \
/* The variable in the conditions prevents `BREAK/CONTINUE` from */\
/* being used outside of the loop with the matching name. */\
if ([[maybe_unused]] constexpr bool _namedloop_InvalidBreakOrContinue = false) \
{ \
[[maybe_unused]] LOOP_NAME_impl_cat(_namedloop_break_,name): break; \
[[maybe_unused]] LOOP_NAME_impl_cat(_namedloop_continue_,name): continue; \
} \
else
#define LOOP_NAME_impl_cat(x, y) LOOP_NAME_impl_cat_(x, y)
#define LOOP_NAME_impl_cat_(x, y) x##y
#define BREAK(name) goto LOOP_NAME_impl_cat(_namedloop_break_,name)
#define CONTINUE(name) goto LOOP_NAME_impl_cat(_namedloop_continue_,name)
#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wkeyword-macro"
#endif
#define break(x) BREAK(x)
#define continue(x) CONTINUE(x)
#ifdef __clang__
#pragma clang diagnostic pop
#endif