Stefan Stanković Stefan Stanković - 5 days ago 6
C++ Question

Using throws to control program flow?

The program communicates with user through

class Menu
, so the
main()
looks like this:

int main() {
try {
Menu menu(/*...*/);
while (true) {
menu.printOptions();
menu.chooseOption();
}
}
catch (const char *error) { /*Resolve error.*/ }
catch (int code) { /*Exit with code.*/ }
}


Current
class Menu
's option used for exiting is as such:

void exit() {
// Release memory.
throw 0;
}


Should constructs like this be avoided and do they have some unpredictable (or undesired) side-effects?

Answer

I would avoid using exceptions as a mean to control flow in that way. Instead you could change your loop, from while (true) to something that checks on the state of the menu class such as while (menu.isAlive()). Exiting is a matter of simply setting the alive attribute to false, which will end the while loop.

Exceptions should be used for situations that the current flow cannot recover from, and that requires you to return control to a parent flow. Having said that, there is nothing that prevents you from using exceptions in that way, but personally I think it is bad enough to have exceptions for error handling, and thereby hidden jumps, but having them for regular flow control, is definitely something I would think polluted the code, and made it less predictable.

Exceptions have the problems that you will also find in many other articles about anti patterns, that:

  • They are similar in many ways to goto statements.
  • Are expensive to use.
  • Makes the code more difficult to read.
  • Is a symptom of a design problem, that should be addressed instead.

On a side note, calling a function exit is a bad idea, since it overloads the std::exit function. And using the std::exit function is not something I would recommend either, since it does not unwind the stack.

There are other answers addressing this on SO and other Stack Exchange sites that might be of interest to you:
Are exceptions as control flow considered a serious antipattern? If so, Why?
Why not use exceptions as regular flow of control?

Comments