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.
Related
I saw a function that uses throw to return something.
I've made some research before asking this, here, about throw and I did not find very much.
If someone could explain me when to use throw to return something and when to use the normal return statement, that would be awesome.
Using throw to return a result can be useful in a deeply nested recursion. Instead of backing out of each call level you get right back up to the top level call for this goal. I think in most other situations it's both too inefficient (because exceptions are optimized for failure handling) and too unconventional to even consider.
return is the easiest and in many situations also the most efficient way to return a computed value, a reference to a class member, a state information (e.g. an enum value), a trivial success/failure information, and, and, and. So this is the most common and usual way to evaluate function values.
throw on the other hand (like Alf already answered) deals with exception's - which, as the name already pretty clearly states :) an exception of the normal control flow: "Something very important (often something bad) happened, which requires an instant handling, I can not continue my usual processing flow and have to throw an exception immediately.". The reason can sometimes be a catastrophic and unrecoverable state in the program, but by no means always. For example, a socket losing its connection is pretty common and not a catastrophy - but can be a reason for throwing an exception nevertheless, because the socket code may be not able to continue computing.
Exceptions are usually a bit more difficult to handle - and to integrate into your program design - than usual return values, and they are - as others already stated - less efficient than simple return values, but they have a lot of benefits.
They can be caught from anywhere in the stack of calling functions
Let's say you write a game, with a game engine (e.g. Ogre), and this engine uses a direct X interface. Now something deep, deep in the DirectX interface happens, which hinders the engine from working correctly.
The error handling of this function (may be 8-10 calls deep in the call stack), which can not work properly anymore, would be nearly impossible if it would be done with normal return values - both for the engine programmers and for the game programmer. So in that case, without exceptions, the method of choice would be a non-standardized error handler - pretty similar to an exception, but not with the powerful possibilities of exceptions. Here's a practical example on how to handle this error with an exception (please ignore the real purpose of the functions, it's just to show the principle:
try
{
mHOQList[mCurrentFrame]->endOcclusionQuery();
} catch( Ogre::Exception& e )
{
if( e.getNumber() == Exception::ERR_RENDERINGAPI_ERROR
&& stdEx::string(e.getDescription()).beginsWith( "End occlusion called" ))
{
// a device lost occurred during our occlusion query. Simply ignore it.
return true;
}
else
throw;
}
We are doing an occlusion query here, which we know can not continue when a "device lost" event happens during it's operation. So we place it in a try/catch clause. When everything works out good in the endOcclusionQuery(), the catch() is never called, and everything is fine.
If an exception is thrown, we first check if we can handle it. We check the number of the exception and its description. If these informations have a specific value, we know that it's a benign error, we can safely ignore it and carry on the next frame. If we don't know how to handle it, we simply throw;, which leaves the handling of the exceplion to a catch() lower in the call hierarchy, which brings me to the next points:
They can be evaluated selectively.
The example above will catch and handle exceptions of the type Ogre::Exception, but nothing else. A std::exception or another exception type is not caught. Let's say for example the endOcclusionQuery() calls a callback in our own code, which then also gets into an exceptional state and throws. We would let this exception pass by and leave it to the lower (or higher) levels of the call hierarchy to handle it.
They can be rethrown.
In the example, we use throw; to re-throw and pass the handling to lower levels in the call hierarchy.
They can be stored and even re-thrown in a separate thread
Imagine a library with hundreds of worker threads, and a manager thread which coordinates these threads. Since exceptions are bound to a single thread, so the manager thread can never catch exceptions from the worker threads. But the worker threads can catch their own exceptions and either handle them if possible or store them, pass them to the manager thread, where it can be rethrown and be handled by the manager thread.
They can be thrown in Constructors
Constructors have no return value, and so it is impossible to check its success with return values. State members are possible, but awkward - they tend to be overlooked. So the preferrable way to deal with errors in a constructor is to throw (of course as a documented behavior). See also Throwing exceptions from constructors
They are standardized
Well when it comes to this, the example above is not the best. Ogre is a pretty old engine, long before C++11, and so the exception classes are proprietary. You can throw anything - from a char to a class LiverSausage. But today this shouldn't be done anymore - std::exception is the class of choice. It contains everything which is needed for a simple exception, and can be inherited for more sophisticated exceptions. It is commonly used and inherited in the STL, and there are helpers classes and functions like std::exception_ptr, std::current_exception() etc.
They can be used as a safe bailout for an unrecoverable program error. At the end, something ugly like this unfortunately can happen in the best programs. You can throw this fatal exception anywhere in your program, and you can catch this exception at a single place, where you can log the error, evaluate where it came from, perhaps even write a dump - so you have at least a clue what could have happened, which is at least less worse than simply crashing ;)
throw isn't used to return any value , it is used to throw exceptions i.e. if you think that a certain condition in the program is going to cause a runtime error or malfunction then you throw a exception which helps to avoid and deal with such runtime errors. Return is used to return from a function and a value to the calling function.
While this might sound bad, I actually let performance be a strong factor in guiding this decision. Most modern optimizers implement what's called zero-cost exception-handling, which ultimately translates to something like, "branch-free normal execution paths, but expensive exceptional paths".
It makes throwing quite expensive in exchange for making your normal execution paths really cheap. I don't have precise numbers for the costs but it's probably relatively extremely expensive if you're using a try/catch block just to test if a key exists in a data structure, e.g.
The other guiding force that I've found useful is the idea of an external exception outside of the programmer's control. Examples of that might be a client failing to connect to a server which should be up after repeated attempts, encountering a corrupt file, failing to allocate memory, things of this sort.
I did get into a debate one time with a colleague about whether a user jamming an abort button on a progress bar qualifies as an exceptional circumstance. I really thought it did because the operation is normally supposed to succeed, and a user aborting is a truly exceptional circumstance outside of the developer's control. On top of that it really simplified the code quite a bit over trying to propagate an abort status down the entire call stack.
In these cases where people might not agree about what is and isn't exceptional control flow, I use performance as like the deciding factor. Here throwing to abort an expensive operation isn't a big performance overhead, since it's not like we're throwing a million times in a critical loop. We're just throwing one time to abort a very expensive operation, and there the overhead of throwing becomes quite trivialized. So that's what I mean when I talk about performance being a deciding factor.
My understanding of the try function, was to stop errors that could possibly occur between try and catch.
But if I do something like this:
std::vector<int> testvector;
testvector.push_back(1);
try{
cout << testvector[53485375345534] << endl;
}catch(...){
}
My idea was that it would not cause an error in the expense for memory, but it does nothing in this case, an error still pops up.
Could someone explain the proper reason for using try, so far in my experience, i could have used an if statement beforehand instead, could someone give me an example when you would need a try statement?
operator [] does not check for bounds in std::vector.
However, std::vector::at() does throw an exception. You should use it instead.
There are different kinds of errors:
Exceptions. These are the errors your program creates, throws and that you can catch and handle.
Access violations, system exceptions and so on, aka "crashes". These are very severe, you can't do much when they occur (at least not inside standard C++'s possibilities), so it's best to write correct programs then these wont crop up.
Assertions. These are meant to check your program logic and constraints during development and testing. They normally appear only in debug code, i.e. they should be turned off in release builds. If an assertion occurs, in Windows a window pops up saying what went wrong.
I am only guessing here - are you using MS Visual Studio?
MSVC's vector implementation checks the operator[]'s argument in debug mode and asserts if the argument indeed is within the vector's range. That assertion is not an exception, so you can't catch it.
Your test case is invalid, std::vector::operator[] doesn't do boundry check, also it doesn't throw exception, you are expecting undefined behavior instead of exception. You could try std::vector::at function
std::vector<int> testvector;
testvector.push_back(1);
try{
std::cout << testvector.at(53485375345534) << endl;
}catch(std::exception& e){
std::cout << e.what() << std::endl;
}
The concept of Try-Catch is about handlings errors which could break your program but most often could be handled without doing so.
Your example is a good one for an operation which is totally correct but only if the data you are requesting exists. That "only if" could be handles by the function itself but then you could never react to the faulty input. Instead the function throws in such cases an exception which can be handle by your code if you surround the calling with a Try-Catch.
Within the Catch block it is often appreciated that you inform the user or at least write the missbehavior to a logfile and you could also load default values or even alter the variables and repeat the function call.
Sometimes the Try-Catch is described as "Ask for forgiveness not for permission" (the latter would be a prior If).
In general the Try-Catch can be read in pseudocode as:
Try:
Do what you think is right to do but be aware it could be wrong...
Catch:
You were too optimistic and should react in a proper way...
I hope that helps to understand the Try-Catch concept a bit better.
When you are using some functions that you are not sure they are going to work, you'll use a throw statement. For example you want to make a GUI windows, you'll use a try block, so in case windows wasn't created, you'll not end up waiting for inputs on a windows that doesn't exist.
I want to know, is it a good practice to place complete code inside a try block or I should place only the code which I feel it will cause a specific exception?
And should I catch basic Exception always
Code 1: complete code in try block
myFunction(){
try{
.........
Code with chance of OneException
.............
}catch(OneException e){
............
}catch(Exception e){
..............
}
}
Code 2: Only the Code with chance of Exception in try block
myFunction(){
.......
try{
Code with chance of OneException
}catch(OneException e){
............
}
............
}
Code 3:Should I catch Exception always
myFunction(){
.......
try{
Code chance of OneException
}catch(OneException e){
............
}catch(Exception e){
..............
}
........
}
Out of this (code1, code2 and code3) which one is the best?
I'm mainly concern with java and C++ coding
Generally speaking, you should only catch exceptions you're interested in and which you can handle. That is...catch an exception where you can do something s.t. the user doesn't perceive the problem or when it is explicitly necessary to tell the user about the problem.
For all other exceptions, let them pop up with all their details (stacktrace etc..) which you obviously log. Note, obviously this doesn't mean the user should also see that exception output but rather a generic error.
Told this, I assume that when you write "Code chance of OneException" you know how to handle OneException, but not Exception, right? So then...only handle OneException.
Always catch exactly what you have to and no more. No matter how much we try, we cannot make our code completely "idiot proof". If someone passes you something which will cause some random error, then it is their job to handle it. If our code handles someone else's exception that has far too much risk of being an unexpected side-effect.
As far as what code to place where: code before the line which could throw the Exception will be run either way, so it does not really make sense to have it inside the try block and before the code which throws. Code after the potential exception should be placed between try and catch if and only if it depends on the exception generating code. So, if your database connection call can fail, place all of the database queries inside the try block.
Limiting the "time" spent in a try...catch makes it easier to read and less prone to accidental catching. I can't tell you how many hours have been lost because someone decided to catch an Exception which should have propagated.
a) It is bad practice, to place complete code inside a try block.
a1) Beside of catching exceptions, a try-block is a documentation where an exception might happen. So place it close to the cause, you have in mind.
a2) In bad circumstances, you have a file for reading, and add later one for writing, but your exception (FileNotFoundException) was written only with the first in mind. A lean scope around the problematic places will help you, identifying further problems.
b) Don't catch basic Exception for completeness or to avoid multiple catch blocks. If you want to write to a file, many things can go wrong: Missing permission, illegal file name, no space left on device, ... . If you present the user a generic Message ("Couldn't write file " + name), he doesn't know what to do. Be as specific as possible, and you can inform him, "Only 20 MB left on device " + devicename + "We need another 8 MB (28 MB in total); please free some space and repeat or choose a different device!"). If you catch "Exception", chances are high, that you're thinking of some exception, but another one occurs, and isn't handled correctly, because the catch-block wasn't written with that possibility in mind.
The best chance to find this exception is, to let it pop up, or, to log it, if the logs are controlled on a regular basis.
It can be a difference between developing an application, which is simply used by end users, or by developing an API, which is used by other developers.
In an API, you often want to wrap an exception into an own exception, to make it easier for users of your api to handle it, and if you have an uniform way to handle exceptions. If your code can throw many exceptions, and would lead to ugly client code, where your customer would need to specify a bunch of exceptions over and over again, you often wrap the exceptions and rethrow them:
try {
...
}
catch {FileNotFoundException fnfe}
{
throw new MyApiException (fnfe);
}
catch {PermissionDeniedException pde}
{
throw new MyApiException (pde);
}
catch {IOException ioe}
{
throw new MyApiException (ioe);
}
That way, your client can decide, how to handle the exception, and will find the specific type of exception, if interested, inside your exception.
As Landei points out, in Java 7 there will be a simplified technique, to catch multiple exceptions, but not only such with a common superclass, see this link here
Wrap the code at the point where you really can handle the exception, and where you can handle the error. If you can't handle the error in the function, then do no wrap the code in try/catch block.
I don't know for java, but in c++ you should catch by const reference :
try
{
// code that can throw an exception
}
catch ( const SomeExceptionType & error )
{
// handle the error
}
C++ isn't Java or C# or... where you need catch (or finally) clauses to clean up after yourself. In C++, RAII does that. Consequently, I rarely ever write try/catch statements in C++, to the point where I consider it a code smell.
So, rather than contemplating which style of code you should use in conjunction with try/catch, you should ask yourself whether you need that try/catch at all.
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."
I can't seem to get my head around why people say C++ exceptions are better. For example, I have an application which loads function objects from shared objects to be used in the application. What goes on is something like this:
bool LoadFunctions()
{
//Get Function factory.
FunctionFactory& oFactory = GetFunctionFactory();
//Create functions from the factory and use.
}
FunctionFactory& GetFunctionFactory()
{
//Get shared object handle.
void* pHandle = dlopen("someso.so");
//Get function ptr for Factory getter.
typedef FunctionFactory* (*tpfFacGet)();
tpfFacGet pF = static_cast<tpfFacGet>(dlsym(pHandle, "GetFactory"));
//Call function and return object.
return *((*pF)());
}
Now, it's easy to see that loads of stuff can go wrong. If I did it like I always do, I'd return pointers instead of references, and I'd check if they were NULL and print an error message and get out if they weren't. That way, I know where things went wrong and I can even try to recover from that (i.e. If I successfully load the factory and fail to load just a single function, I may still continue). What I don't understand is how to use exceptions in such a scenario and how to recover the program rather than printing an error message and qutting. Can someone tell me how I am to do this in C++ish way?
We don't even need return codes. If a problem occurs it should be in the exception.
int main()
{
try
{
LoadFunctions();
// if we're here, everything succeeded!
}
catch(std::exception _e)
{
// output exception message, quit gracefully
}
// IRRESPECTIVE OF SUCCESS/FAILURE WE END UP HERE
return 0;
} // eo main
EDIT:
Okay, so lets say that you have an alternative method of loading functions should LoadFunctions() fail. You might be tempted to call that in the catch handler, but this way you'll quickly end up with a huge amount of nested exception handlers which just complicates things.
So now we get down to the question of design. LoadFunctions should succeed if functions are loaded and throw out an exception if it does not. In this hypothetical example of an alternative method of loading functions, that call should be within the LoadFunctions method. This alternative method does not need to be visible to the caller.
At the top level we either end up with functions, or we do not. Writing good exception handling, in my opinion is about getting rid of grey areas. The function did what it was told to do, or it didn't.
There is, as you say, a lot that can go wrong. You won't catch a bad cast there by the way. If the symbol exists but is not the type you are casting it to, you will just get a nasty shock later.
If you were to avoid exceptions you will need somewhere to report the error. As your LoadFunctions and GetFunctionFactory() do not know how you wish to handle the error (log it? print it to stderr? Put up a message box?) The only thing it can do is generate the error.
A common way do to that in C is to pass in a parameter into which it can put the error if one occurs, and for each function to "check" success before continuing. This can make the flow rather tricky.
The C++ concept of "throwing" the exception means that you do not need to keep passing a pointer (or reference) through each function. Where the error occurs you generate it and "throw" it - a bit like "shouting" it. This causes all code (other than cleanup in destructors) to halt until it finds a catcher that handles the error the way that is required.
Note that exceptions should only generally be used to handle errors, not a normal occurrence like encountering "end of file" when this is the way you know a read has completed.
Using exceptions instead of return-values (or any other method) is not supposed to change the behaviour of the code, only how it is written and organized. That means basically that first you decide what your recovery of a certain error is, be it more graceful or less, then you write the code to perform that.
Most experienced programmers (all practically) agree that exceptions are a much better method than return values. You can't see the big difference in short examples of a few functions, but in real systems of thousands of functions and types you would see it clearly. I will not get into more details of how it is better.
I suggest anyway you should just get yourself used to using exceptions by default. However note that using exceptions has some somewhat delicate issues (e.g. RAII http://en.wikipedia.org/wiki/RAII), that ultimately make your code better, but you should read about them in a book (I won't be able to describe here and feel that I do justice to the subject).
I think the book "Effective c++ / Scott Meyer" deals with that, certainly "Exceptional C++ / Herb Sutter". These books are a good jump start for any c++ developer if you havent read them anyway.