goto statement

I know that in general it is best to avoid goto statements, but I am in a situation and I can't think of a way around using one.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
if(/*some condition*/)
{
//code
for(/*loop*/)
{
bool some_statement = false;
//code to determine if some_statement should be true
if(some_statement)
goto out_of_if_block;
}
//code in case goto is not executed
}
return a_value;
out_of_if_block;
//code in case of execution of goto statement
return different_value;


I am wondering if anyone has encountered a similar problem and knows a way out of it, breaking out of a for loop inside of an if statement.

also is my having the return statement setup legal and moral?

edit 1: in case anyone is wondering the fcn I am writing takes the inverse of a matrix, the method I am using (gaussian elimination?) halfway through you need to check if one of the rows is all zeros if it is, you need to stop as the matrix is non-invertible, which is the purpose of the goto command.
Last edited on
The main problems with goto is that it may unwittingly skip over object ctors, and (when used improperly) it can make the code harder to follow.

I looks like you're using goto to catch an error condition. In which case you might want to consider using an exception instead:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
try
{
  if(/*something*/)
  {
    for(/*loop*/)
    {
      bool some_statement = false;

        //...

      if(some_statement)
        throw 0;          // instead of throwing '0' you can throw an error code
    }
  }

  return a_value;
}
catch(int errcode)
{
  // ...
  return different_value;
}


There are ways to do it without goto or exceptions -- although they get kind of ugly.

Anyway it's all about personal preference.
I am not familiar w/ exception handling and try-catch blocks.

for each try block can you have only one catch block?
1
2
3
4
5
for( /* stuff */ )
{
    if( condition )
         break;
}


works just fine. No need for try/catch in this case.
I also need to break out of an if statement enclosing the for loop
and he also needs to do different code on success and on failure. Though I guess you could double-up on if(conditions) (put one outside the loop as well).

This is what I was talking about where it gets messy, although now that I wrote sample code out it doesn't seem that messy at all.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
if( foo )
{
  for( stuff )
  {
    if(fail_condition)
      break;
  }

  if(fail_condition)
  {
    //do failure stuff here
  }
  else
  {
    //do success stuff here
  }
}
I also need to break out of an if statement enclosing the for loop


You only need one break to do this. The break indicated by jsmith does exactly that!

he also needs to do different code on success and on failure.


Does he? Couldn't there be other reasons for breaking out of the loop early? maybe the loop just needs to end for whatever reason. It could be that something was found and the loop doesn't need to continue. Although try...catch could work, jsmith's idea could work as well. Lastly, he could simply set a flag that causes the loop to end. There are at least two other ways that this situation could be handled without goto. Personally I think that using goto is unacceptable in this scenario.

@jsmith/kempo: when I wrote a program to test whether jsmith's idea would help, it did not work
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include<iostream>

main()
{
	if(true)
	{
		for(;;true)
			if(true)
				break;
		std::cout<<"this doesn't work"<<std::endl;
	}
       //in order for this to work the way I needed it to break would need to get to here, while this
       //might work in java with labeled loops, I am not writing in Java.
	std::cout<<"done"<<std::endl;
}


My apologies is my explanation of what I wanted was not clear.

@disch thank you for answer, your first post was most helpful, while your second suggestion while I would have used normally, the function was horribly complicated and would have made the code a mess, but thank you.

@kempo: turn down the aggression a little, I posted this question to try and get away out of using goto. and disch's suggestion was helpful as a) it was correct, and b) I have learned a new of doing something.

Yes, in that case you'll need Disch's solution.
Topic archived. No new replies allowed.