Is it better to check the values โ€‹โ€‹before moving on to the library function or to catch the exception?

Let's say I use a library with the to_int function, which takes a string parameter. This function returns int if the string is a character representation of a number, for example, "23" will return 23 . If the string is not a number, it throws std::runtime_error . Would be better:

 if(is_all_digits(str)) x = to_int(str); else output("not an int, idiot. Try again"); 

or

 try { x = to_int(str); } catch(...) { output("not an int, idiot. Try again"); } 
+6
source share
4 answers

There are several different error handling methods, each of which has its advantages and disadvantages.

Consider the getAllElements() function, which receives a container with some elements.

Now this can lead to an error (connecting to the database or something else). You now have options

 Errorcode getAllElements(std::vector<...> & cont); 

or

 std::vector<...> getAllElements(); //throws exceptions 

This is usually a matter of general design and depends on the circumstances. I prefer the option with exceptions for several reasons. I can just assign and not need a predefined container

 auto elements = getAllElements(); 

In the next case, will you handle your errors? If you treat them as 5 functions above on the stack, you should check the error code each time and just pass it to the next function. The exception will be automatically propagated until someone catches it and can not cope with it.


Exceptions have a definite drawback. They cause a larger binary and slower when an exception is thrown. Because of this, exceptions are usually not used in game development. (Listen to this for more information on this: http://cppcast.com/2016/10/guy-davidson/ they talk about why not use exceptions. I currently don't have a timestamp.)

Exceptions should also be used in exceptional cases. Errors that you cannot deal with immediately, and should be addressed somewhere above.


So, if you do not need high performance / small binary, I would suggest using exceptions in which they are useful. They can result in less code being typed (for example, checking return codes), which can lead to fewer places for errors to be entered.

The error handling mechanism from CppCon 2016 is also well discussed here: CppCon 2016: Patrice Roy "Situation with Exemption"

+2
source

There is no single answer to this question, since it depends on how the program as a whole can work with bad input and whether it can reasonably recover when errors are detected (regardless of whether these errors are reported using return codes or by throwing exceptions) .

Can every function that calls to_int() recover immediately from incorrect input? If not, it is better to allow an exception ... so it unwinds the stack until some caller appears (with a try/catch ) that can actually recover from the error.

What if you have many functions that call to_int() , do you want to check in each? If so, this leads to a lot of code duplication.

What if you have a function that calls to_int() , which can recover immediately due to an error, and some others that cannot?

What if you want to report an error to the caller (for example, to allow something more substantial than writing an error line)?

What is not is_all_digits() function? If this is not the case, what if you implement it in such a way as to skip some errors detected by to_int() ? Then you have the worst of both worlds - performing error checking in an attempt to prevent the generation of exceptions, but then the function throws an exception anyway. For example, there may be some global parameter that forces to_int() to accept only octal digits (in the range of 0 to 7 ), but your is_all_digits() function considers all decimal digits to be valid.

More generally, the real need is to define an error handling strategy that works for your program as a whole. An attempt to solve based on the use of a single function between exceptions or exception exceptions is completely absent.

If your program has an error message using exceptions (for example, with one central try/catch in main() , so all errors propagate to the call stack, so main() implements recovery all over the world), and then throws exceptions. If for every function of your program it makes sense to detect errors and quietly handle them in place, avoid exceptions.

What I'm defending allows the dog (your program) to swing its tail (low-level decisions on how to handle errors). Your question, in fact, asks the question of whether to allow the tail to wallow the dog.

+1
source

If the caught exception is really specific, than you can use a certain try catch (using a common catch attempt is not a good idea, since you are hiding a bunch of other possible errors)

In general, my preference is to check the string before passing it to the function.

0
source

When you use a library or API, you want this to prevent you from bad habits and other mistakes.

This is the role of your function to control the integrity of these parameters and to eliminate exceptions.

Note that you can also use assertions when developing code, and then turn it off for binary production.

0
source

All Articles