I am trying to figure out the best way to deal with exceptions.
C++ says that any datatype can be thrown as an exception, but there is no way to tell what data type has been thrown, which makes exceptions essentially worthless. However, I am assuming that these days everyone throw std::exception, so that is safe in a catch. Is that a fair assumption?
(I am building a library that will be used by others, so has to fit in with other code that I do not control.)
The Exception.what function returns a char * (not a string) with no way to free it. Of course, that string should contain information about the exception, for example if a file is not found then the name of the file that was not found. I assume that we just tolerate a small memory leak here when exceptions are thrown. Correct?
It is unclear how reliably stack traces can be generated in a general way and sent to a log file. (In a production environment when things go wrong, not in a debugger.) So I was thinking of inserting otherwise redundant try/catch blocks at interesting places in the code which can add logging and append extra information to the what text and then rethrow a new exception. But that process will, of course, destroy any stack trace. For example
foo = stuff();
try {
processStuff()
} catch (std::exception& ex) {
string msg = "While processing " + foo.toString() + ": " + ex.what;
log << msg;
throw std::exception((char[])msg);
}
Is that the best approach?
There are lots of articles that describe the basic classes but nothing I could find on how to really make them work in practice. Links appreciated.
(Here again I am trying to write Java/.Net in C++. Is that a hopeless cause?)
Type of exception
What type of exception object can be thrown is part of the function / method's public contract.
Often, libraries may introduce their own exception types which may or may not inherit from std::exception.
Recommended: throw std::exception or an exception inherited from it. Document the type(s) of exception thrown. Usually, you will have a "library default", such as
Unless stated otherwise, all methods and functions in this library may throw an exception of type mylib::exception or a type inherited from it.
char * what()
The (implied?) assumption is that the pointer is valid as long as the exception object is valid. No necessity to free the string manually, no reason for leak.
If you need to store the text for later, make a copy of it - e.g. by assigning to std::string.
Stack traces
... are not part of the C++ standard. Furthermore, most compiler implementations allow generating code that does not allow re-discovering a stack trace. (the respective option usually says something about "stack frame").
However, for most compilers, libraries exist that can add this stack trace, but this usually requires access to the debug symbols.
"Redundant" try/catch
You might need them anyway.
The perfect exception must support different aspects:
it contains instructions or hints for the end user how to remove a blocking issue ("Cannot open file bibbit.txt because it is read only")
it contains information for support and development why the error occurred, allowing them to possibly avoid it / handle it better in the future. (Such as ... the stack trace)
it needs to allow calling code to detect known exceptions and handle them specifically (e.g. the file the user wants to open is read-only, ask user if they want to open in read-only mode, and try again)
Rarely an exception does all that perfectly. But repackaging at certain "layers" helps a lot here - even though this makes us lose some of the beauty of exceptions.
Does that help?
Edit regarding your edit:
Generally ok, but DO NOT re-construct the exception. Change your code to:
...
catch (std::exception& ex) {
string msg = "While processing " + foo.toString() + ": " + ex.what;
log << msg;
throw; // <--- !!!!!!
}
This re-throws the original exception, so catch handlers further down can still distinguish the different types:
void Foo() {
class random_exception : public std::exception { ... }
try {
...
if (rand() % 2) throw random_exception();
...
}
catch(std::exception const & x)
{
log << x.what();
throw;
}
}
int main()
{
try {
Foo();
}
catch(random_exception const & x)
{
cout << "A random exception occurred, you can try again";
}
catch(std::exception const & x)
{
cout << This didn't work. " << x.what();
}
catch(...) // catches all exception types, but you don't know what
{
cout << "Uh, oh, you are doomed.".
}
}
Of course, that's an issue when repackaging the exception.
Some things I'm leaning to:
The exception type to be thrown is a thin wrapper around a (smart) pointer. This allows storing exceptions (e.g. to pass them to another thread, or as an "inner exception" when repackaging) without losing type information:
I allow separate messages for end user and for diagnostics. End user message is required, diagnostics is usually generated from (and contains) the error code and context. User will see no "weird numbers and techie gibberish" unless they click on "details".
Instead of including parameters in the error message:
msg = "Could not open file bibbit.txt (tried 5 times)"; // :-(
I use a fixed message, and a list of (name, value) parameters.
msg = "Could not open file"; // :-)
msg.Add("filename", filename).Add("retries", retryCount);
This should simplify localization, and allows the caller to access individual attributes for known errors, allowing more specific handling.
However, I am assuming that these days everyone throw std::Exception, so that is safe in a catch. Is that a fair assumption?
That's mostly a safe assumption. Some people insist in throwing random stuff, but it's not your business - if you are a library you throw exceptions and at most you catch your own, you shouldn't be concerned with what other people throw (your code should use RAII anyway to avoid resource leaks - this covers even the case where e.g. callbacks throw stuff you don't know).
The Exception.what function returns a char * (not a string) with no way to free it. Of course, that string should contain information about the exception, for example if a file is not found then the name of the file that was not found. I assume that we just tolerate a small memory leak here when exceptions are thrown. Correct?
Nope. The string returned by what normally does not result in a memory leak. Either is statically allocated (I've seen many simple exception classes that just return a string literal) or it's managed inside the exception itself (std::runtime_error normally contains an std::string, with what returning the result of its c_str method). In general, you can assume that whatever what results is there as long as the exception lives - if you need it outside the catch block copy it into an std::string or something.
This is actually required by the standard:
The return value remains valid until the exception object from which it is obtained is destroyed or a non-const member function of the exception object is called.
(C++11, §18.8.1 ¶10)
It is unclear how reliably stack traces can be generated in a general way and sent to a log file. (In a production environment when things go wrong, not in a debugger.) So I was thinking of inserting otherwise redundant try/catch blocks at interesting places in the code which can add logging and append extra information to the what text and then rethrow a new exception. But that process will, of course, destroy any stack trace.
Stack traces in C++ are a sad story; there's no portable way to generate them, you have to resort to platform-specific calls (or to libraries that abstract them); personally I used several approaches in the past:
on a new, multi-platform Qt application I wrote my own "fat" exception class, which saved the stack trace (I derived from booster::exception, which already bundles the stack trace-saving part) and added the possibility to add extra information while the exception gets caught and rethrown, similar to how Boost.Exception is implemented (important: Boost.Exception != booster::exception, they are completely unrelated); see here, it's full of Qt types but you can get the idea;
on a legacy project which throw the most bizarre types (and there's no way to change them to a common exception type) I just hooked (via linker tricks) the throw and I always save the stack trace in a global circular buffer, which is printed out if an exception is not caught.
Your approach is flawed because not only it loses parts of the stack trace, but even the type information about the exception. Look up how Boost.Exception does its thing to see how to do it right. Also, you never, ever throw a new (=heap allocated) exception, otherwise freeing it becomes a burden to people who want to catch it (also, probably nobody will catch it because no one catches by pointer, you normally catch by reference).
It looks like std::stack_trace will be part of C++ 23.
Under GCC (yes, I know, not universal), you can use std::current_exception to get information about the current exception. For instance, the following code will return the mangled name of the exception type:
std::string current_exception_type()
{
std::string result;
if (std::current_exception())
{
auto p = std::current_exception().__cxa_exception_type();
if (p)
{
result = p->name();
}
}
return result;
}
To demangle the name, you can use:
std::string demangle_cpp(char const* name)
{
std::string result;
char* demangled(nullptr);
try
{
int status;
demangled = abi::__cxa_demangle(name, 0, 0, &status);
if (demangled != nullptr) result = demangled;
} catch(...)
{
}
if (demangled != nullptr) free(demangled);
return result;
}
Related
Java person here stuck doing some c++. I'm catching an exception and trying to diagnose where it is coming from (regrettably the exception is not thrown when run via gdb). However, when I print out the what() of the exception I simply get the string "std::exception". Is this specific to anything in the standard library or do lots of standard exceptions return this? Here is what I am doing to print:
} catch (const std::exception & ex) {
std::cout << ex.what() << std::endl;
}
The output is just:
std::exception
Also, I'm working in a fairly large code-base, it is possible that this is coming from some exception on our end but I have yet to find it through regular search techniques so I'm currently leaning towards this coming from the standard libraries.
I'm using g++ 4.8 if that is relevant.
This could be because of two things:
Someone just does throw std::exception() somewhere, which is not very helpful.
A class derived from std::exception gets copied to std::exception. This is a problem called Object Slicing.
I just made the second mistake myself actually. I had this code:
try
{
// Some Boost stuff
}
catch (std::exception e)
{
cerr << e.what() << endl;
}
You must make sure to do std::exception& e. I know you didn't make this mistake but it's possible someone else did further within the code (or someone coming here from Google).
C++ exceptions are completely different from Java exceptions.
The C++ standard specifies that the string returned by what() is completely arbitrary, and implementation-defined:
virtual const char* what() const noexcept;
Returns: An implementation-defined ntbs.
Remarks: The message may be a null-terminated multibyte string
(17.5.2.1.4.2), suitable for conversion
and display as a wstring (21.3, 22.4.1.4). The return value remains
valid until the exception object
from which it is obtained is destroyed or a non-const member
function of the exception object is called.
The return value you're getting, "std::exception" is perfectly compliant with the C++ standard.
Don't rely on C++ exceptions to tell you exactly where they were thrown from after you catch them, like Java does. This is outside of the scope of the C++ standard. In C++, an exception is really nothing more than a mechanism for transferring execution control flow.
Having said that: many C++ implementation will provide you with some implementation-specific mechanisms for dumping the current stack backtrace, to the best of the runtime library's abilities. Check your C++ compiler's documentation for more information.
gcc, for example, offers backtrace(), together with some gcc internal functions to convert the raw addresses returned by backtrace() into symbols, and other functions for demangling the symbols. Using that, a rough analogue to Java's exception handling can be concocted; although gcc's implementation isn't perfect, and has some functional holes, and that also requires advance planning, and custom exception classes whose constructors capture the current stack frame (before the exception gets actually thrown); and, once caught, the thrown exception class instance can be inspected for the captured backtrace information.
But that doesn't really help your current situation. I would suggest that you check your C++ compiler's documentation, as I suggested, and also investigate your debugger's capabilities. A C++ debugger should allow you to set a breakpoint when any exceptions get thrown, and before it is caught, so that you can examine the stack backtrace via the debugger, when the exception occurs.
This question already has answers here:
Is there a general consensus in the C++ community on when exceptions should be used? [closed]
(11 answers)
Closed 9 years ago.
I have used in many places if...else statements, however I'm new to exception handling. What is the main difference among these two?
for eg:
int *ptr = new (nothrow) int[1000];
if (ptr == NULL) {
// Handle error cases here...
}
OR
try
{
int* myarray= new int[1000];
}
catch (exception& e)
{
cout << "Standard exception: " << e.what() << endl;
}
So we are using here standard class for exception which has some in build function like e.what(). So it may be advantage. Other than that all other functionality handling we can do using if...else also. Is there any other merits in using exception handling?
To collect what the comments say in an answer:
since the standardization in 1998, new does not return a null pointer at failure but throws an exception, namely std::bad_alloc. This is different to C's malloc and maybe to some early pre-standard implementations of C++, where new might have returned NULL as well (I don't know, tbh).
There is a possibility in C++, to get a nullpointer on allocation failure instead of an exception as well:
int *ptr = new(std::nothrow) int[1000];
So in short, the first code you have will not work as intended, as it is an attempt of C-style error handling in the presence of C++ exceptions. If allocation fails, the exception will be thrown, the if block will never be entered and the program probably will be terminated since you don't catch the bad_alloc.
There are lots of articles comparing general error handling with exceptions vs return codes, and it would go way to far trying to cover the topic here. Amongst the reasons for exceptions are
Function return types are not occupied by the error handling but can return real values - no "output" function parameters needed.
You do not need to handle the return of every single function call in every single function but can just catch the exception some levels up the call stack where you actually can handle the error
Exceptions can pass arbitraty information to the error handling site, as compared to one global errno variable and a single returned error code.
The main difference is that the version using exception handling at least might work, where the one using the if statement can't possibly work.
Your first snippet:
int *ptr = new int[1000];
if (ptr == NULL) {
// Handle error cases here...
}
...seems to assume that new will return a null pointer in case of failure. While that was true at one time, it hasn't been in a long time. With any reasonably current compiler, the new has only two possibilities: succeed or throw. Therefore, your second version aligns with how C++ is supposed to work.
If you really want to use this style, you can rewrite the code to get it to return a null pointer in case of failure:
int *ptr = new(nothrow) int[1000];
if (ptr == NULL) {
// Handle error cases here...
}
In most cases, you shouldn't be using new directly anyway -- you should really use std::vector<int> p(1000); and be done with it.
With that out of the way, I feel obliged to add that for an awful lot of code, it probably makes the most sense to do neither and simply assume that the memory allocation will succeed.
At one time (MS-DOS) it was fairly common for memory allocation to actually fail if you tried to allocate more memory than was available -- but that was a long time ago. Nowadays, things aren't so simple (as a rule). Current systems use virtual memory, which makes the situation much more complicated.
On Linux, what'll typically happen is that even the memory isn't really available, Linux will do what's called an "overdcommit". You'll still get a non-null pointer as if the allocation had succeeded -- but when you try to use the memory, bad things will happen. Specifically, Linux has what's called an "OOM Killer" that basically assumes that running out of memory is a sign of a bug, so if it happens, it tries to find the buggy program(s), and kills it/them. For most practical purpose, this means your program will probably be killed, and other (semi-arbitrarily chosen) ones may be as well.
Windows stays a little closer to the model C++ expects, so if (for example) your code were running on an unattended server, the allocation might actually fail. Long before it fails, however, it'll drag the rest of the machine to its knees, madly swapping in a doomed attempt at making the allocation succeed. If the user is actually operating the machine at the time, they'll typically either kill your program or else kill some others to free up enough memory for your code to get the requested memory fairly quickly.
In none of these cases is it particularly realistic to program against the assumption that an allocation can fail though. For most practical purposes, one of two things happens: either the allocation succeeds, or the program dies.
That leads back to the previous advice: in a typical case, you should generally just use std::vector, and assume your allocation will succeed. If you need to provide availability beyond that, you just about need to do it some other way (such as re-starting the process if it dies, preferably in a way that uses less memory).
As already mentioned, your original if-else example would still throw an exception from C++98 onwards, though adding nothrow (as edited) should make it work as desired (return null, thus trigger if-statement).
Below I'll assume, for simplicity, that, for if-else to handle exceptions, we have functions returning false on exception.
Some advantages of exceptions above if-else, off the top of my head:
You know the type of the exception for logging / debugging / bug fixing
Example:
When a function throws an exception, you can, to a reasonable extent, tell whether there may be a problem with the code or something that you can't do much about like an out of memory exception.
With the if-else, when a function returns false, you have no idea what happened in that function.
You can of course have separate logging to record this information, but why not just return an exception with the exception details included instead?
You needn't have a mess of if-else conditions to propagate the exception to the calling function
Example: (comments included to indicate behaviour)
bool someFunction() // may return false on exception
{
if (someFunction2()) // may return false on exception
return false;
if (someFunction3()) // may return false on exception
return false;
return someFunction4(); // may return false on exception
}
(There are many people who don't like having functions with multiple return statements. In this case, you'll have an even messier function.)
As opposed to:
void someFunction() // may throw exception
{
someFunction2(); // may throw exception
someFunction3(); // may throw exception
someFunction4(); // may throw exception
}
An alternative to, or extension of, if-else is error codes. For this, the second point will remain. See this for more on the comparison between that and exceptions.
If you handle the error locally, if ... else is cleaner. If the function where the error occurs doesn't handle the error, then throw an exception to pass off to someone higher in the call chain.
First of all your first code with if statement will terminate program in case of exception thrown by new[] operator because of not handled exception. You can check such thing here for example: http://www.cplusplus.com/reference/new/operator%20new%5B%5D/
Also exceptions are thrown in many other cases, not only when allocation failed and their main feature (in my eyes) is moving control in application up (to place where exception is handled). I recommend you read some more about exceptions, good read would be "More Effective C++" by Scott Meyers, there is great chapter on exceptions.
I mean, I knew all the language rules about throw, try {} catch {}, but I am not sure if I am using them correctly in the real world. Please see the following example:
We have a large piece of scientific code which did all sorts of image processing things, recently we decided to spruce it up and make it more robust. One of the routines which is frequently used is void rotate_in_place(float* image, image_size sz);
To make it more robust, we add some sanity check at the beginning of the code:
void rotate_in_place(float* image, image_size sz) {
// rotate_in_place does not support non-square image;
if (sz.nx != sz.ny) throw NonSquareImageError;
// rotate_in_place does not support image too small or too large
if (sz.nx <= 2 || sz.nx > 1024) throw WrongImageSizeError;
// Real rode here
.....
}
Now the problem is that rotate_in_place() is used in over 1000 places, shall I wrap each call of rotate_in_place() with try{} catch {}, this looks to me will make code incredibly bloated. Another possibility is do not wrap any try{} catch{} and let the program exit, but how is this different from just using
if (sz.nx != sz.ny) {
cerr << "Error: non-squared image error!\n";
exit(0);
}
In short, I am not so sure about the real benefit of using throw, try, catch, any good suggestions?
Every site that handles the error needs try-catch block. It all depends on your design, but I doubt you need to handle the error in every rotate_in_place call-site, you probably get away from propagating upwards most of the time.
Printing the error and using exit is bad for three reasons:
You can't handle the error. exit is not handling (unless it's done when the error is absolutely critical, but your function cannot know that — caller might have a way to recover).
You're extending responsibilities of the function with writing to a hard-coded stream, which might not even be available (this is rotate_in_place, not rotate_in_place_and_print_errors_and_kill_the_program_if_something_is_wrong) — this hurts reusability.
You lose all debugging information with this approach (you can generate stack traces from unhandled exceptions, you can't do anything with a function that bails out every time — unhandled exception is a bug, but it's a bug you can follow to the source).
The general rule for exceptions is, "Does the immediate call site care about what's going on here?" If the call site does care, then returning a status code probably makes sense. Otherwise, throwing makes more sense.
Consider it this way -- sure, your rotate in place method has a couple of invalid argument types, in which case you should probably throw std::invalid_argument. It's unlikely that a caller of rotate_in_place wants to deal with or knows how to deal with the case that an image was not square, for example, and therefore that's probably better expressed as an exception.
Another possibility is do not wrap any try{} catch{} and let the
program exit, but how is this different from just using
if (sz.nx != sz.ny) {
cerr << "Error: non-squared image error!\n";
exit(0);
}
It's different because if someone later wants to take your function and put it in, say, a GUI application, they don't have to terminate the program based on the error. They can turn that exception into something pretty for the user or something like that.
It also has benefits for you right now -- namely that you don't have to pull <iostream> into that translation unit simply to do error writing.
I usually use a pattern something like this:
int realEntryPoint()
{
//Program goes here
}
int main()
{
//Allow the debugger to get the exception if this is a debug binary
#ifdef NDEBUG
try
#endif
{
return realEntryPoint();
}
#ifdef NDEBUG
catch (std::exception& ex)
{
std::cerr << "An exception was thrown: " << ex.what() << std::endl;
}
#endif
}
Now the problem is that rotate_in_place() is used in over 1000 places, shall I wrap each call of rotate_in_place() with try{} catch {}, this looks to me will make code incredibly bloated.
It will, and it beats the purpose of using exceptions in the first place.
Another possibility is do not wrap any try{} catch{} and let the program exit, but how is this different from just using [...]
That you can always change the location of exception handling later on. If at some point you find a better place to sensibly handle the error (perhaps recovering from it), then that's the point where you put the catch. Sometimes that's in the very function where you throw the exception; sometimes it's way up in the call chain.
Do put a catch-all in main, just in case. Deriving exceptions from standard ones such as std::runtime_error makes doing this a lot easier.
The point in using exception handling holds in following simple rules:
As soon as anything bad can happen due to bad user input (internal logic should be handled via assertions/logging), throw an exception. Throw as soon as possible, and as much as possible: C++ exceptions are usually pretty cheap compared to say, .Net ones.
Let an exception propagate if you can't handle the error. This means pretty much always.
The thing to remember is: The exception should bubble up to the point where it can be handled. This can mean a dialog box with some formatting of the error, or this can imply that some unimportant piece of logic won't be executed after all, etc.
Using exceptions allows the caller to decide how to handle an error. If you called exit directly within the function, then the program would exit without the caller being able to decide how to handle the error. Also, with exit, stack objects would not be unwound. :-(
What you can do is to make rotate_in_place return a boolean if the function call was succesfull. And return the rotated image via a function parameter.
bool rotate_in_place(float* image, image_size sz, float** rotated_image) {
// rotate_in_place does not support non-square image;
if (sz.nx != sz.ny) return false;
// rotate_in_place does not support image too small or too large
if (sz.nx <= 2 || sz.nx > 1024) return false;
// Real rode here
.....
return true;
}
It depends.
Exceptions are generally meant to be caught/handled. In your case, is it possible to handle the exception (for instance, the user provides a non-square image, so you ask them to try again). However if there is nothing you can do about it, then cerr is the way to go.
Well, I agree that really using Exceptions results in bloated code. That is the main reason for me not liking them.
Anyway, as to your example: The key difference between throwing exceptions and just using exit() is that, since the handling of the exception happens (or is supposed to happen) outside of the program fragment that generated the error/exception, you do not specify how the user of a function/class has to handle the error. By using exceptions you allow different treatments like aborting the program, reporting errors or even recovering from certain errors.
TLDNR: If you use exceptions, the exception-generating part of the code does not need to specify how the exceptional case is treated. That happens in the outside program and can be changed depending on how the code is being used.
I'm trying to understand error handling in C++.
I have read that using try, throw, catch is better style and less complicated than using if statements with return values. But I'm not sure I really understand how try, throw, catch works. I made a simple example below and it would be great to get feedback about any problems or bad style. My goal is to make a function out of the example that checks the results of another calculation.
Here are questions I have about try, throw, catch:
(1) Should the catch statement be included in my function? Or should it be somewhere else, like in main() or in the function where the initial calculation is done?
(2) Is it overkill to use try, catch, throw for something this simple (I would like to improve my style)?
(3) If there is an error, I would like to terminate the program. How would I do that? Or does "catch" mean that that is done automatically?
(4) I don't understand the use of cerr. Why not just use cout? Have I used cerr correctly here? Should I also have used it in the if/else statements?
Thanks a lot for any help.
Here's the example I made:
double calculated = 10.2; // from previous calculation
double tolerance = 0.3; // I can set this in this function
double valueWanted = 10.0; // from previous calculation
const int calcError = 5; // I picked this number randomly to use for indicating an error
try
{
if (fabs(fTargetValue - fCalculated) <= fTolerance)
cout << "Result is within range.";
else
cout << "Failed.";
throw calcError;
}
catch (const int calcError)
{
cerr << "The calculation failed.\n" << endl;
}
Well that's a lot of questions. I will try to give you some hints :
(1) Do not include the try-catch in your function. Throwing an exception is done to tell the outer world that something happened. If you can handle the problem in your function, do not throw at all ^^ A good error handling is generally to catch the error ASAP (in the caller) or in a general purpose handler far away like in main, to handle gracefully unhandled errors.
(2) As a rule of thumb, use exception for ... exceptional things. Errors are good candidate for exceptional things. An exception could be thrown for things like overflow or division by zero in a math library. You have to decide, but in general it is good to handle errors with exceptions.
(3) catch do not mean that your program will end. In fact it is the contrary. By catching an exception, you say that you will handle the problem ^^ If you want to terminate, a simple way in a simple program is to not catch exception, as the default behavior for uncaught exception is program termination ^^ Instead, you can explicitly terminate your program in some catch block.
(4) cerr is just like cout, but is a different file descriptor. It means that external programs can differentiate cerr from cout. It is used for error, but that's not really important but for external programs.
my2c
Ok, firstly your example will throw every time because you do not have scope braces after the else. Therefore, only cout << "Failed."; will be executed and throw calcError will be executed each time, regardless of whether the result was in range or not. Change this to:
else
{
cout << "Failed.";
throw calcError;
}
In the event that an exception is throw, the code will begin within the catch block you have defined, stating the calculation failed.
If the result was in range (throw is never called), code will begin executed directly after your catch block.
When you throw a type, that type arrives at the catch handler. This allows you to define catch handlers for different types. In this case, you are throwing (and catching) a const int. That's all good. Generally, we throw std::exception or a derivation of this. Your own exception classes can contain information pertinent to the error. In your case you could include a simple message that it was out of range, or indeed include the const int that failed.
The catch statement should be in the first function up from the one that throws (maybe in the function that throws) that can recover from the exception and allow the program to continue normally.
Yes, there's no point throwing really if you expect to be catching it. Also, your normal program flow shouldn't throw. As a rule of thumb, only throw for when you get into a situation you don't really expect should ever happen. Exceptions are called exceptions because they happen in exceptional circumstances. Often a good time to use exceptions is when interacting with the programs environment. You usually expect certain things to work, eg to be able to allocate memory, open a file, receive a complete data packet from a network device etc. All these cases should result in an exception being thrown. Also, if your program receives input, it should initially validate it. But, later on, during processing, if there's something wrong with the data that should already have been rejected by the validation, such as a divide by zero occurring because of strange input data, that would also be an exceptional situation. IF you rely on exceptions too much for when expected things happen, the flow and logic of your program can become overly difficult to reason about and the program maintenance gets unnecessarily hard.
If there is an error, just don't catch. If there's no catch, the exception will go all the way up to your main function, and will then go to the runtime from there which will terminate your program. And, for some O.S.s such as windows this will cause a minidump file to be created which you could use to debug your program with to find out what exception caused it to terminate.
cerr and cout just give you two ways of outputting information from your program. In cases where another program consumes the output of your program to do something, it will read cout and expect to understand it. This means if you want to write out errors or warning that the consuming program won't understand you have to write them to cerr so that you don't confuse the second program that's reading your programs normal cout output.
The C++ standard has a few exception classes that are all derivable from. I suggest you do that instead of throwing and catching PODs. It's not hard, either, and would improve (and specify the type of error) like so
class CalculationError : std::invalid_argument
{
public:
CalculationError(std::string const& msg)
: std::invalid_argument(msg)
{}
};
For a quick overview of the exception hierarchy go to http://www.richelbilderbeek.nl/CppExceptionHierarchy.htm
The problem is: when you throw a POD type, there is no attached message. The great part about throwing exceptions is the ability to write out a message about what might have gone wrong, and how to fix it. This is not possible when throwing an int.
There are three output streams in C++: log, cerr, and cout. Each of them are represented differently, which means that, when starting your program, you can use the command line to filter out each of these streams. This is great for debugging then, as you can filter by cerr and see if your program failed a test.
Example: my_program > out.txt 2> log.txt (cout goes to out.txt, the others to log.txt)
However, I would recommend not just cerring. Usually, the point of a catch is to reverse program state! If you, for example, tried to allocate a dynamic array, and that fails, the catch would be responsible for destructing the array again before rethrowing. Otherwise, you would have a whole bunch of things like memory leaks and whatnot.
What's also important to note is that, once caught, the exception is "swallowed". If you cannot or do not want to deal with the error here, it is best to write
catch(/* Error to be caught */)
{
throw; // Rethrows original exception, propagating it upwards
}
If you want some good literature about this, Herb Sutter wrote a book called Exceptional C++ and it covers exception safety in a practical and enlightening way (imo). It's definitely worth checking out if you want to know when and why you need to throw exceptions.
Hope this helps!
Did not you forget a block around the else case
try
{
if (fabs(fTargetValue - fCalculated) <= fTolerance)
cout << "Result is within range.";
else {
cout << "Failed.";
throw calcError;
}
}
There are lots of good answers here for your questions. I was just reading about cerr and I would like to share what I was reading here. The source is "C++ Basic Structures: Vectors, Pointers, Strings, and Files" course in Coursera platform.
Here is the quote:
"When printing error messages, cerr is preferred over cout. cerr is not bufferred, which means it is not stored in memory to be printed later on. It just gets printed immediately. Therefore, as a rule of thumb, important data and variables should be printed with cout while error messages should be printed with cerr."
Also:
"cerr is an unbuffered output stream. This means that the output is immediately printed and not stored for later. This makes cerr more suitable for use with error messages where its storage is not important.
On the other hand, cout is buffered, meaning its output is temporary stored so that the system can retrieve it later for quicker access. cout is more suitable for important data and variables that are used throughout the program."
Each time I have seen the catch all statement:
try
{
// some code
}
catch (...)
{
}
it has always been an abuse.
The arguments against using cache all clauses are obvious. It will catch anything including OS generated exceptions such as access violations.
Since the exception handler can't know what it's dealing with, in most cases the exceptions will manifest as obscure log messages or some incoherent message box.
So catch(...) seems inherently evil.
But it is still implemented in C++ and other languages (Java, C#) implements similar mechanisms. So is there some cases when its usage is justified?
(1) It's not true that the statement will catch OS exceptions. Your use of the term "Access Violation" betrays a Windows background; it was true for older MSVC++ versions.
(2) Regardsless, the catch-all behavior is useful for threads with specific purposes. Catching the failure allows the thread to report it failed. Without it, the other parts of the program need to deal with the possibility of a thread just disappearing. It also allows you to log which thread failed, and the arguments used to start the thread.
The case where it's justified in general is when you log the exception (or do something similar) or do some cleanup, and then immediately rethrow.
In C++ in particular, logging in a catch(...) block is pretty pointless since you don't have any way to obtain the exception, and cleanup is pointless because you should be using RAII for that. Using it in destructors seems to be about the only legitimate case.
the arguments against using cache all clauses are obvious , it will catch anything including OS generated exceptions such as access violation. since the exception handler can't know what its dealing with, in most cases the exceptions will manifest as obscure log message or some incoherent message box.
And if those same exceptions aren't caught you get... an incoherent message box.
catch(...) lets me at least present my own message box (and invoke custom logging, save a crash dump, etc.).
I think there are also reasonable uses of catch(...) in destructors. Destructors can't throw--well, I mean, they can throw, but if a destructor throws during stack unwinding due to an in-progress exception the program terminates, so they should not ever allow exceptions to escape. It is in general better to allow the first exception to continue to be unwound than to terminate the program.
Another situation is in a worker thread that can run arbitrary functions; generally you don't want an unceremonious crash if the task throws an exception. A catch(...) in the worker thread provides the opportunity for semi-orderly clean-up and shutdown.
In addition to what other posters have already said, I'd like to mention one nice point from the C++ Standard:
If no matching handler is found in a
program, the function std::terminate()
is called; whether or not the stack is
unwound before this call to
std::terminate() is
implementation-defined.
(15.3/9)
This means that main() and every thread function must be wrapped in a catch-all handler; otherwise, one can't even be sure that destructors for automatic objects will be called if an uncaught exception is thrown.
try {...} catch (...) is needed around body of callback function which is called from code
that doesn't understand C++ exceptions (usually C library).
Otherwise, if some C++ library you use throws an exception that doesn't derive from
std::exception, it will probably cause calling code to crash or corrupt its internal state.
Instead you should catch this exception and either finish program immediately or
return some error code (meaning "we are doomed and I don't know why", but it's still better
then letting C++ exception to pass through).
Around thread procedure. Mostly because of the same reason as 1.
And because otherwise thread failure would pass unnoticed.
catch(...) has been useful for me in two circumstances, both of which are unjustified (I can't even remember the second)
The first is my overall application safety. While throwing exceptions that don't derive from std::exception is a No-No, I have one just in case in my main() function:
int execute(void); // real program lies here
int main(void)
{
try
{
return execute();
}
catch(const std::exception& e)
{
// or similar
std::cerr << "Unhandled exception: " << e.what() << std::endl;
return EXIT_FAILURE;
}
catch(...)
{
std::cerr << "Unknown exception!" << std::endl;
return EXIT_FAILURE;
}
}
Now, it's only there "just in case", and it's not really justified. There should be no reason to ever enter that catch clause, as that would mean somebody has done a Bad Thing. Observe how useless the statement really is; "Something bad happened, no clue what!" It's only a step above just crashing in the first place.
The second use might be in destructors or some other function that needs to do manual management before letting the exception propagate. That's not really a justification either, as things should clean themselves up safely with RAII. But I may have used it once or twice for some reason I can't recall, and I can't see a reason to ever do so again.
catch (...) allows you to write code in which you can legitimately claim a guarantee that your code will not crash even when you are not in long term complete control of the submodules your code depends on. Your claim is tantamount to claiming that this semantic cannot be used except as a means of abuse. Maybe so, but military specifications may differ from you on this issue.
catch(...) is necessary in the absence of the finally clause as found in other languages:
try {
...
} catch(...) {
cleanup...
throw;
}
The alternative - making stack objects to 'own' everything - is often much more code and less readable and maintainable. The platform API is often C, and does not come with it conveniently bundled.
It is also useful around plugin code that you do not control or simply do not trust from a stability perspective. It won't stop them crashing, but it might keep things a little saner.
Finally, there are times when you really do not care about the outcome of something.