Alternative to C++ exception - c++

I'm writing a reactive software, which repeatedly recieves input, processes it and emits relevant output. The main loop looks something like:
initialize();
while (true) {
Message msg,out;
recieve(msg);
process(msg,out);
//no global state is saved between loop iterations!
send(out);
}
I want that whatever error occured during the proccess phase, whetehr it is out of memory error, logical error, invalid assertion etc, the program will clean up whatever it did, and keep running. I'll assume it is invalid input, and simply ignore it.
C++'s exception are exceptionally good for that situation, I could surround process with try/catch clause, and throw exception whenever something goes wrog. The only thing I need to make sure that I clean up all my resources before throwing an exception. This could be verified by RAII, or by writing a global resource allocator (for instance, if your destructor might throw an exception), and use it exclusively for all resources.
Socket s = GlobalResourceHandler.manageSocket(new Socket());
...
try {
process(msg,out);
catch (...) {
GlobalResourceHandler.cleanUp();
}
However, using exception is forbidden in our coding standard (also in Google's C++ standard BTW), as a result all the code is compiled with exceptions off, and I believe nobody's going to change the way everything work just for my design problem.
Also, this is code for embedded platform, so the less C++ extra feature we use, the faster the code becomes, and the more portable it is.
Is there an alternative design I can consider?
update:
I appreciate everyones answer about idiotic code standard. The only thing I can say is, in big organizations you have to have strict and sometimes illogical rules, to make sure no idiot would come and make your good code unmaintainable. The standard is more about people than about technicalities. Yes, bad man can make every code a mess, but it's much worse if you give him extra tools for the task.
I'm still looking for a technical answer.

Coding these kind of services all day long I understand your problem. Although we do have exceptions within our code, we don't return them to the external libraries that invoke it, instead we have a simple 'tribool'.
enum ReturnCode
{
OK = 0, // OK (there is a reason for it to be 0)
KO, // An error occurred, wait for next message
FATAL // A critical error occurred, reboot
};
I must say FATAL is... exceptional. There isn't any code path in the application that returns it, apart from the initialization (can't do much if you're not initialized properly).
C++ here brings much with RAII, since it laughs multiple paths of return off and guarantees deterministic release of the objects it holds.
For the actual code checking, you can simply use some macros:
// Here is the reason for OK being 0 and KO and Fatal being something else
#define CHECK_RETURN(Expr) if (ReturnCode code = (Expr)) return code;
#define CHECK_BREAK(Expr) if (ReturnCode code = (Expr)) \
if (KO == code) break; else return code;
Then you can use them like so:
CHECK_RETURN( initialize() )
while(true)
{
Message msg,out;
CHECK_BREAK( receive(msg) )
CHECK_BREAK( process(msg,out) )
CHECK_BREAK( send(out) )
}
As noted, the real bummer is about constructors. You can't have "normal" constructors with such a situation.
Perhaps can you use boost::optional, if you can't, I would really suggest duplicating the functionality. Combine that with systemic factory functions in lieu of constructors and you're off to go:
boost::optional<MyObject> obj = MyObject::Build(1, 2, 3);
if (!obj) return KO;
obj->foo();
Looks much like a pointer, except that it's stack allocated and thus involves near zero overhead.

If you can't throw an exception, then the alternative is to return (or to return false or similar error code).
Whether you throw or return, you still use C++ deterministic destructors to release resources.
The one thing that you can't easily just 'return' from is a constructor. If you have an unrecoverable error in a constructor, then it's a good time to throw; but if you're not allowed to throw, then instead you must return, and in that case you need some other way to signal construction failure:
Have private constructors and static factory methods; have the factory method return null on construction failure; don't forget to check for a null return when you call a factory method
Have a "get_isConstructedOk()" property which you invoke after each constructor (and don't forget to invoke/check it on every newly-constructed object)
Implement 'two-stage' construction: in which you say that any code which might fail mustn't be in a constructor, and must instead be in a separate bool initialize() method that's called after the constructor (and don't forget to call initialize and don't forget to check its return value).

However, using exception is forbidden
in our coding standard (also in
Google's C++ standard BTW). Is there
an alternative design I can consider?
Short answer is no.
Long answer yes :). You can make all functions return an error code (similar to the implementation of Microsoft's COM platform.
The main disadvantages of this approach are:
you have to handle all exceptional cases explicitly
your code size increases dramatically
the code becomes more difficult to read.
Instead of:
initialize();
while (true) {
Message msg,out;
recieve(msg);
process(msg,out);
//no global state is saved between loop iterations!
send(out);
}
you have:
if( !succeedded( initialize() ) )
return SOME_ERROR;
while (true) {
Message msg,out;
if( !succeeded( RetVal rv = recieve(msg) ) )
{
SomeErrorHandler(rv);
break;
}
if( !succeeded( RetVal rv = process(msg,out) ) )
{
SomeErrorHandler(rv);
break;
}
//no global state is saved between loop iterations!
if( !succeeded( RetVal rv = send(out) ) )
{
SomeErrorHandler(rv);
break;
}
}
furthermore, the implementation all your functions will have to do the same: surround each function call with an if.
In the example above, you also have to decide if the rv value on each iteration constitutes an error for the current function and (eventually) return it directly from the while, or break the while on any error, and return the value.
In short, except for possibly using RAII in your code and templates (are you allowed to use them?), you end up close to "C code, using the C++ compiler".
Your code transforms each function from a two-liner into an eight-liner and so on. You can improve this with use of extra functions and #defined macros but macros have their own idiosyncrasies that you have to be really careful about.
In short, your coding standards are making your code unnecessarily longer, more error prone, harder to understand and more difficult to maintain.
This is a good case to present to whoever is in charge of the coding standards in your company :(
Edit: You can also implement this with signals but they are a bad replacement for exceptions: they do the same thing as exceptions, only they also disable RAII completely and make your code even less elegant and more error prone.

Just because using exceptions is forbidden in your current coding standards this does not mean that you should dismiss them out of hand for future problems you encounter such as this. It may the case that your current coding standards did not envisage such a scenario arising. If they did they would probably give you help as to what the alternative implementation would be.
This sounds to me like a good time to challenge your current coding standards. If the people that wrote them are still there then speak to them directly as they will either be able to answer your question as to alternative strategies or they will accept that this is a valid use-case for exceptions.

However, using exception is forbidden in our coding standard (also in Google's C++ standard BTW). Is there an alternative design I can consider?
Coding standards like that are nuts.
I suggest that you ask the person / people who developed and mandated that standard how to solve your problem. If they have no good answer, use this as justification for ignoring that part of the coding standard ... with your bosses permission of course.

If you are running under windows, you could use SEH exceptions. They also have the advantage of pre-stack-unwind handler which can stop unwind (EXCEPTION_CONTINUE_EXECUTION).

Off the top of my head, you might be able to achieve something similar with signals.
Set up a signal handler to catch appropriate signals and have it clean things up. For example, if your code generates a SIGSEGV as a result of something that would otherwise have thrown an exception a little earlier, you can try catching it with the signal handler.
There may be more to it than this as I have not thought it through.
Hope this helps.

Do you call any libraries that could raise exceptions? If it's the case, you will need a try catch anyway. For your internal errors, each method will need to return an error code (use return only for error code, use reference parameters to return the actual values). If you want to make memory cleanup 100% reliable, you could start your application using a monitor application. If your application crash, the monitor start it again. You still need to close files and DB connection, tho.

Another approach is, instead of throwing exception, set a global error indicator, and return a legal but arbitary input. Then checking in every loop iteration whether or not the global error indicator is set, and if it is - return.
If you're careful enough, you can make sure that returning legal data will never cause you to crash or to cause undefined behaviour. Thus you shouldn't care that the software will keep running a bit until it reaches to the nearest error checking condition.
For example
#define WHILE_R(cond,return_value) while (cond) {\
if (exception_thrown) return return_value
#define ENDWHILE() }
bool isPolyLegal(Poly p) {
PolyIter it(p);
WHILE_R(it.next(),true) //return value is arbitary
...
if (not_enough_memory) exception_thrown = true;
...
ENDWHILE()
}

Related

How do you write the error checking part of a method to make it readable and error prone?

I had a disagreement with another programmer on how to write a method with a lot of error checking:
public void performAction() {
if (test1) {
if (test2) {
if (test3) {
// DO STUFF
} else {
return "error 3";
}
} else {
return "error 2";
}
} else {
return "error 1";
}
}
-
public void performAction() {
if (!test1) {
return "error 1";
}
if (!test2) {
return "error 1";
}
if (!test3) {
return "error 1";
}
// DO STUFF
}
To me, the deep nesting of if statements makes the first example hard to read.
The second one, despite having three returns, is more readable.
I checked by curiosity what Code Complete was saying about that and it left me less sure about the way to handle this:
The stack of error conditions at the bottom of the nest is a sign of well-written error-processing code.
but then
Indenting the main body of the routine inside four if statements is aesthetically ugly, especially if there’s much code inside the innermost if statement.
and considering using guard clauses, as in the second example
Minimize the number of returns in each routine. It’s harder to understand a routine when, reading it at the bottom, you’re unaware of the possibility that it returned some-where above.
How do you write the error checking part of a method to make it readable and error-prone?
Nothing gets programmers into a fight faster than stylistic debates (Is it ever advantageous to use 'goto' in a language that supports loops and functions? If so, why?). So the short answer is "Whatever style you and your team decide is best for your project/language."
That being said, I would like to add my 2 cents to Code Complete's comment about multiple returns. You should make a distinction between multiple successful returns, and multiple returns. If I need to investigate 5 returns that are not due to errors being generated, the function probably needs to be rewritten. If you gracefully exit your function immediately after an error is detected, then a maintenance programmer (i.e. you in 6 months) should have no more trouble following the main logic of your function than if you had nested all of those error checks.
So, my personal opinion is that your second code example is the better choice.
This is my opinion.
The old mantra of "Minimize the number of returns in each routine" seem to be a bit dated. It is highly applicable when you have methods longer 8-10 lines of code, where lots of operations are executed.
The newer schools of thought, emphasizing Single Responsibility and very short methods, would seem to render that a bit unnecessary. When your whole method does not do any operations directly, but simply handles the error processing, multiple returns in a clean format would be best.
In either case, any time you have nested ifs, the readable suffers substantially.
The one optimization I would make is to use an if-else-if structure, to clearly indicate the logic flow.
Sample code:
public void Execute()
{
if (test1)
{
return;
}
else if (test2)
{
return;
}
PerformAction();
}
private void PerformAction()
{
//DO STUFF
}
If you're using a language with exception-handling and automated resource management, your colleagues should probably get used to your preferred style with premature exits in the case of encountering a external input error.
The idea of trying to shift function exits towards the bottom of the scope was useful in the days before exception handling and automated resource management (ex: languages without destructors or GC like C) because error recovery often required manual cleanup.
In those manual cleanup cases, it was often useful to shift the exits towards the bottom of a function so that you could look at the top of the function for the logic creating the temporary resources needed by the function and towards the bottom of the function to see the symmetrical clean up of those resources.
In such cases as with assembly, it's quite common to see jumps/branches to an error label at the bottom of the function where the clean up would occur. It's also not too uncommon even in C using gotos for this purpose.
Also, as mentioned, deep nesting introduces a lot of mental overhead. Your brain has to function like a deeply-nested stack trying to remember where you're at, and as even Linus Torvalds, a diehard C coder, likes to say: if you need something like 4 nested levels of indentation in a single function, your code is already broken and should be refactored (I'm not sure I agree with him about the precise number, but he has a point in terms of how it obfuscates logic).
When you move into a more modern language like C++, you now have automated resource management via destructors. Functions should then no longer be mentioning cleanup details, as the resources should handle the cleanup automatically by conforming to what's called the resource acquisition is initialization idiom (not exactly the best name). That eliminates one of the big reasons to favor a style that strives to have error handling logic towards the bottom.
On top of that, when you use a language like C++, it potentially throws exceptions and all over the place. So it's not uncommon for every other line of code to have the effect of having a hidden, implicit exit with logic like this:
if an exception occurs:
automatically cleanup resources and propagate the error
So there are hidden, premature exits all over the place. So if you use a language like that, not only should you get used to premature exits in the case of an exception, but you're kind of forced into it and have no other choice. As far as readability/traceability is concerned in those languages, you can't get any simpler than:
if something bad happened:
return error
The one exception I'd suggest to the rule is static branch prediction. If you're writing very performance-critical code where the smallest of micro-efficiencies counts more than readability, then you want your branches to be weighted towards favoring the common case line of execution as Intel advises. So instead of:
if something exceptional happened:
return error
... for performance you might invert the logic and do this instead:
if something normal happened:
...
return success
return error

Error handling technique for procedural hardware programming

I am writing a C++ code that controls a special device that is the fusion of several SDKs. My code looks like
#define sdk1SafeCall(err) __sdk1SafeCall(err,__FILE__,__LINE__)
int errorcode = 0;
sdk1SafeCall(sdk1_InitializeDevice());
errorcode=sdk2_InitializeDevice();
errorcode=sdk3_InitializeDevice();
if (some_parameter)
{
errorcode=sdk2_readDevice(true);
}
else
{
errorcode=sdk3_writeDevice();
}
label again: errorcode=sdk1_readDevice();
if (error) goto again;
errorcode=close_everything();
Use parameters will rearrange the control flow. My current method uses something like cudaSafeCall to wrap the error codes and exit. What I don't know how to do is where to store detailed explanations of these errors or how to recover from them (such as the goto example). At the end of the day the code looks really messy.
Edit
I do sometimes handle errors with a wrapper.
Writing error-safe code is hard. In your pseudocode, you don't actually deal with errors at all. errorcode will just have the result of "close_everything()" - which may have succeeded, even if everything else went wrong.
The typical way to solve this sort of thing in C++ is to have an object for each "resource" (e.g. a "device"), and throw an exception if something goes wrong that you don't expect to recover from. Wrap the whole function [or an outer set of functions] in a try/catch block.
Of course, if "failure is normal" (e.g. you try to read from a network port, and you get a timeout because there was no data available, that's not something you should throw an exception for). This should use a return-value.
Note that using objects to handle resources requires careful design of the code and especially that your destructor does a good job of cleaning it is run after an exception. Make sure you don't leave things behind if you throw an exception in a constructor - as that is how you get leaks.
There are naturally a whole host of other solutions - after all, we're talking programming, so there's always at least 11 different ways to solve something.

Correct Exceptions in C++

I am just learning how to handle errors in my C++ code. I wrote this example that looks for a text file called some file, and if its not found will throw an exception.
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
int array[90];
try
{
ifstream file;
file.open("somefile.txt");
if(!file.good())
throw 56;
}
catch(int e)
{
cout<<"Error number "<<e<<endl;
}
return 0;
}
Now I have two questions. First I would like to know if I am using Exceptions correctly. Second, (assuming the first is true) what is the benefit to using them vs an If else statement?
"Correctly" is a value judgment, but (unlike other classes) there's a major benefit from exceptions classes being a monolithic hierarchy, so I'd generally advise throwing something derived from std::exception, not simply an int.
Second, it's open to question whether an incorrect file name is sufficiently unexpected to qualify as a good reason to throw an exception at all.
As to benefits vs. an if/else statement: there are a couple. First, exceptions let you segregate the code that deals with errors, so the main idea and readability of the code don't get lost in a maze of error handling. Second, when you have several layers of code between throwing and catching the exception, the code that throws the exception may not know how it should really be handled. Your code, for example, uses std::cout to report the problem -- but most such code would report errors on std::cerr instead. You can change from one to the other without any change to the code that tried to open the file (which might be deep in a library, and have no clue of which should be used for this application -- and might be used in an application where both are wrong, and MessageBox was preferred).
First I would like to know if I am using Exceptions correctly.
Yes, though generally you want your exceptions to derive from std::exception.
Second, (assuming the first is true) what is the benefit to using them vs an If else statement?
For the given example, nothing. The benefit of exceptions comes when you have
many deep nested functions, like this.
#include <stdexcept>
#include <iostream>
#include <string>
void anErrorFunc(const std::string& x)
{
ifstream file;
file.open(x);
if (!file)
throw std::runtime_error("Could not open file");
}
void someOtherFunction(const std::string& y)
{
//Do stuff
anErrorFunc(y);
//Do other stuff
}
int main()
{
try {
someOtherFunction("somefile.txt");
} catch (std::exception &ex) {
std::cout << "Ouch! That hurts, because: "
<< ex.what() << "!\n";
}
}
Note that the exception will be caught in main(), and someOtherFunction
does not have to worry about dealing with passing through failure return codes.
Well, you are using exception correctly in that there is nothing wrong with your code. That said, typically we do not throw primitive types around (even though you can). It is generally a better idea to throw an object that derives from std::exception, and even better to throw an std::exception that is also a boost::exception.
When things are very simple and the handling code and the throwing code are in the same function, then there really is no reason to use exceptions instead of if statements (and, indeed, it would be faster and more efficient to use if...else in that particular case). However, in most situations, the point where the error is discovered and you need to report it is far removed from the logic where the error is to be handled. In many cases the error-recovery logic is specific to the application in question and the logic where the error is discovered cannot make a sensible choice about how to recover from the error, hence the need to throw.
Another benefit of exception handling is that the type of the exception can be used to convey the type of error that occurred. Usually the types in exception hierarchies are much more meaningful than those error codes that end up being used in C code. Also, you cannot ignore an exception as easily as you can ignore an error code; while you can ignore an exception, it will cause the program to die a horrible death. By contrast, if a C function returns an error status code, and you ignore it, it's possible to continue executing and get silently wrong results... in that sense, the use of exceptions is much safer than using error codes.
You may also be interested in reading about exceptions and error handling from the C++ FAQ Lite.
You are not using exceptions correctly. Your code has a much simpler equivalent, without exceptions, which provides the same behaviour.
Exceptions are for when you can't test the results of a function call with other methods. In this case you can, so you shouldn't use exceptions.
As a corollary, you shouldn't throw and catch the exception in the same function body - just do whatever you want to do instead of throwing it.
Syntactically speaking, your code is correct. Idiomatically speaking, maybe not so much -- or at least this depends on the context. When a file can't open then we might do our handling right there inside that if( !file.good() ) if it's perfectly common and possible to happen. For example, if the user asks to open a file in a text editor then it's perfectly plausible and common that the file doesn't exist. On the other hand, if the editor can't find the spelling corpus file then that means something is (arguably) terribly wrong. The program wasn't probably installed, or the user messed around with that file -- anything is possible.
In C++ we use exceptions for exceptional cases. That is, cases that are really not meant to happen and that we don't "accept" to happen. This is as opposed to a user file not opening, or an invalid user input, or no internet connection: these are all examples of perfectly valid things happening, common situations, things we expect to happen sooner or later in a program's run. They aren't exceptional.
Now, what are the benefits of using exceptions compared to conditionals? Allow me to extend this question to any other jump (goto) mechanism: returns as well as conditionals. Exceptions are more expressive if that's what you want to say: if you are dealing with an exceptional case then use exceptions. Exceptions also get more done than plain conditionals, in an analogous way to that of virtual functions getting more done than conditionals. The right code-block will be executed depending on the exception, but also the right scope will handle the exception depending on the handlers.
There are other advantages to exceptions compared with conditionals: exceptions separate error-handling from other code. They allow associating arbitrary data and actions with an error state. They allow communicating success states (via a return) as well as error state (via a throw). And the list goes on...
Technically speaking and at the lowest level exceptions are a sophisticated jump mechanism. Back in the butterfly-days people invented the if conditional as a somewhat-sophisticated goto in order to enhance expressiveness (because a goto can be used for anything really) and to reduce programmer errors. The looping constructs such as the C for loop are also in essence a sophisticated jump with sparkles and rainbow colours, again for reducing errors and enhancing expressiveness. C++ introduced its new casting operators for the same reasons.
So there: exceptions aren't magic, just something somewhat new in the scene compared to conditionals and loops. Don't use them when you don't mean to, just like you don't use a loop when you really mean to use a conditional.
Syntactically what you're doing is right. Style-wise, as others have noted, you should be throwing something descended from std::exception.
As to part two of your question, I'd like to go into more detail on that.
The whole point of exceptions is to separate policy from implementation. As Billy ONeal said, you get no benefit at all from using exceptions within the same function that an if statement wouldn't make better. You need to be deeply nested in function calls for it to make sense.
In most code, your high level code has enough information and context to know what to do about errors, but no mechanism to detect them. Your low level code can detect the errors but has none of the information needed to deal with them.
The traditional means of coping with this -- returning error codes -- has a few problems:
It clutters up the code with error handling code to the point that the actual logic is obfuscated.
It relies on programmers not being lazy and checking EVERY error code return, an often foolhardy assumption. (C programmers, be honest here: when was the last time you checked the return value of printf?)
It adds the overhead of error checking and handling to EVERY function call whether there's an error or not.
Exceptions solve these issues (with varying degrees of success).
Exceptions solve #1 by only having exception-related code at the point of detection and at the point of handling. Intervening functions don't get cluttered with handling for obscure errors that they themselves have no interest in nor capability of dealing with.
They solve #2 by forcing handling. You can't ignore an exception. You have to take action on them. (Lazy programmers can still catch all exceptions and then ignore them, but here their crippling inability to program is now highlighted for all to see.)
They solve #3 (when not naively implemented) by having near-zero costs when not used, albeit often at a very, very high cost when actually used.
This is not to say that exceptions are the end-all/be-all of error handling. The disadvantages:
Exceptions are usually very costly when used. They have to be eschewed, despite their advantages, if performance is paramount.
Exceptions lead to very opaque code at times. They are non-local transfers of control -- effectively slightly safer versions of goto statements, but across functions. An exception can transfer control from hundreds of layers deep in your code in source files not even slightly related to the ones you're working on (and, in fact, quite possibly not even accessible to you). This kind of "spooky action at a distance" can make code very difficult to figure out.
"Checked exceptions" can actually be worse for noise generation than the old-style if handling. They tend to be more verbose, you see, than if or switch statements and the fact that you must handle checked exceptions for the code to even compile makes them a liability to many situations.
Because of their often high cost of use, carelessly using them for all error handling can make your code slow and bloated.

Do you consider this technique "BAD"?

Sometimes you need to skip execution of part of a method under certain non-critical error conditions. You can use exceptions for that, but exceptions generally are not recommended in normal application logic, only for abnormal situations.
So I do a trick like this:
do
{
bool isGood = true;
.... some code
if(!isGood)
break;
.... some more code
if(!isGood)
break;
.... some more code
} while(false);
..... some other code, which has to be executed.
I use a "fake" loop which will run once, and I can abort it by break or continue.
Some of my colleagues did not like that, and they called it "bad practice". I personally find that approach pretty slick. But what do you think?
Bad practice, it depends.
What I see in this code is a very creative way to write "goto" with less sulphur-smelling keywords.
There are multiple alternatives to this code, which can or can not be better, depending on the situation.
Your do/while solution
Your solution is interesting if you have a lot of code, but will evaluate the "exit" of this processing at some limited points:
do
{
bool isError = false ;
/* some code, perhaps setting isError to true */
if(isError) break ;
/* some code, perhaps setting isError to true */
if(isError) break ;
/* some code, perhaps setting isError to true */
}
while(false) ;
// some other code
The problem is that you can't easily use your "if(isError) break ;" is a loop, because it will only exit the inner loop, not your do/while block.
And of course, if the failure is inside another function, the function must return some kind of error code, and your code must not forget to interpret the error code correctly.
I won't discuss alternatives using ifs or even nested ifs because, after some thinking, I find them inferior solutions than your own for your problem.
Calling a goto a... goto
Perhaps you should put clearly on the table the fact you're using a goto, and document the reasons you choose this solution over another.
At least, it will show something could be wrong with the code, and prompt reviewers to validate or invalidate your solution.
You must still open a block, and instead of breaking, use a goto.
{
// etc.
if(/*some failure condition*/) goto MY_EXIT ;
// etc.
while(/* etc.*/)
{
// etc.
for(/* etc.*/)
{
// etc.
if(/*some failure condition*/) goto MY_EXIT ;
// etc.
}
// etc.
if(/*some failure condition*/) goto MY_EXIT ;
// etc.
}
// etc.
}
MY_EXIT:
// some other code
This way, as you exit the block through the goto, there is no way for you to bypass some object constructor with the goto (which is forbidden by C++).
This problem solves the process exiting from nested loops problem (and using goto to exit nested loops is an example given by B. Stroustrup as a valid use of goto), but it won't solve the fact some functions calls could fail and be ignored (because someone failed to test correctly their return code, if any).
Of course, now, you can exit your process from multiple points, from multiple loop nesting depth, so if it is a problem...
try/catch
If the code is not supposed to fail (so, failure is exceptional), or even if the code structure can fail, but is overly complex to exit, then the following approach could be clearer:
try
{
// All your code
// You can throw the moment something fails
// Note that you can call functions, use reccursion,
// have multiple loops, etc. it won't change
// anything: If you want to exit the process,
// then throw a MyExitProcessException exception.
if(/* etc. */)
{
// etc.
while(/* etc.*/)
{
// etc.
for(/* etc.*/)
{
// etc.
if(/*some failure condition*/) throw MyExitProcessException() ;
// etc.
}
// etc.
callSomeFunction() ;
// the function will throw if the condition is met
// so no need to test a return code
// etc.
}
// etc.
}
// etc.
}
catch(const MyExitProcessException & e)
{
// To avoid catching other exceptions, you should
// define a "MyExitProcessException" exception
}
// some other code
If some condition in the code above, or inside some functions called by the code above, is not met, then throw an exception.
This is somewhat weightier than your do/while solution, but has the same advantages, and can even abort the processing from inside loops or from inside called functions.
Discussion
Your need seems to come from the fact you can have a complex process to execute (code, functions calls, loops, etc.), but you want to interrupt it over some condition (probably either failure, or because it succeeded sooner than excepted). If you can rewrite it in a different way, you should do it. But perhaps, there is no other way.
Let's assume that.
If you can code it with a try/catch, do it: To interrupt a complex piece of code, throwing an exception is the right solution (the fact you can add failure/success info inside your exception object should not be underestimated). You will have a clearer code after that.
Now, if you're in a speed bottleneck, resolving your problem with thrown exceptions as an exit is not the fastest way to do it.
No one can deny your solution is a glorified goto. There won't be a goto-spaghetti code, because the do/while won't let you do that, but it is still a semantic goto. This can be the reasons some could find this code "bad": They smell the goto without finding its keyword clearly.
In this case (and in this performance, profiled-verified) case only, your solution seems Ok, and better than the alternative using if), but of lesser quality (IMHO) than the goto solution which at least, doesn't hide itself behind a false loop.
Conclusion
As far as I am concerned, I find your solution creative, but I would stick to the thrown exception solution.
So, in order of preference:
Use try/catch
Use goto
Use your do/while loop
Use ifs/nested ifs
You're pretty much just disguising a "goto" as a fake loop. Whether you like gotos or not, you'd be just as far ahead using a real undisguised goto.
Personally, I'd just write it as
bool isGood = true;
.... some code
if(isGood)
{
.... some more code
}
if(isGood)
{
.... some more code
}
Why use a fake loop? You can do the same thing with a method and it probably won't be considered a "bad practice" as it is more expected.
someMethod()
{
.... some code
if(!isGood)
return;
.... some more code
if(!isGood)
return;
.... some more code
}
You have complicated non-linear control flow inside a difficult to recognize idiom. So, yes, I think this technique is bad.
It might be worthwhile to spend sometime trying to figure out if this can be written a little nicer.
This is convoluted and confusing, I would scrap it immediately.
Consider this alternative:
private void DoSomething()
{
// some code
if (some condition)
{
return;
}
// some more code
if (some other condition)
{
return;
}
// yet more code
}
Also consider breaking up the code above into more than one method.
public bool Method1(){ ... }
public bool Method2(){ ... }
public void DoStuff(){
bool everythingWorked = Method1() && Method2();
... stuff you want executed always ...
}
The reason why this works is due to something called short circuit logic. Method2 won't be called if Method1 returns false.
This also has the additional benefit that you can break your method into smaller chunks, which will be easier to unit test.
What you're trying to do is non-local failure recovery. This is what goto is for. Use it. (actually, this is what exception handling is for -- but if you can't use that, 'goto' or 'setjmp/longjmp' are the next best thing).
This pattern, the if(succeeded(..)) pattern, and 'goto cleanup', all 3 are semantically and structurally equivalent. Use whichever one is most common in your code project. There's much value in consistency.
I would caution against if(failed(..)) break; on one point in that you're producing a surprising result should you try to nest loops:
do{
bool isGood = true;
.... some code
if(!isGood)
break;
.... some more code
for(....){
if(!isGood)
break; // <-- OOPS, this will exit the 'for' loop, which
// probably isn't what the author intended
.... some more code
}
} while(false);
..... some other code, which has to be executed.
Neither goto cleanup nor if(succeeded(..)) have this surprise, so I'd encourage using one of these two instead.
Basically you just described goto. I use goto in C all the time. I don't consider it bad, unless you use it to emulate a loop (never ever do that!). My typical usage of goto in C is to emulate exceptions (C has no exceptions):
// Code
if (bad_thing_happened) goto catch;
// More code
if (bad_thing_happened) goto catch;
// Even more code
finally:
// This code is executed in any case
// whether we have an exception or not,
// just like finally statement in other
// languages
return whatever;
catch:
// Code to handle bad error condition
// Make sure code tagged for finally
// is executed in any case
goto finally;
Except for the fact that catch and finally have opposite order, I fail to see why this code should be BAD just because it uses goto, if a real try/catch/finally code works exactly like this and just doesn't use goto. That makes no sense. And thus I fail to see why your code should be tagged as BAD.
Refactor. The clean solution will in most cases be to split this code out into a smaller helper function, from which you can return, rather than breaking out of your not-actually-a-loop.
Then you can substitute your break's for return's, and now people can immediately make sense of your code when reading it, instead of having to stop and wonder why you made this loop which doesn't actually loop.
Yes, I'd say that simply because it doesn't behave as the reader would expect, it's a bad practice. The principle of least surprise, and so on. When I see a loop, I expect it to loop, and if it doesn't, I have to stop and wonder why.
I have no problem with that as long as the code is readable.
I have used this idiom for years. I find it preferable to the similar nested or serial ifs , the "goto onError", or having multiple returns. The above example with the nested loop is something to watch out for. I always add a comment on the "do" to make it clear to anyone new to the idiom.
For better or worse, I have used the construct in a few places. The start of it is clearly documented, though:
/* This is a one-cycle loop that simplifies error handling */
do
{
...modestly complex code, including a nested loop...
} while (0);
This is in C, rather than C++ - so exceptions aren't an option. If I were using C++, I would consider seriously using exceptions to handle exceptions. The repeated test idiom suggested by Jeremy is also reasonable; I have used that more frequently. RAII would help me greatly, too; sadly, C does not support that easily. And using more functions would help. Handling breaks from inside the nested loop is done by repeated test.
I would not classify it as a great style; I would not automatically categorize it as "BAD".
It depends on what the alternatives are. You have to admit that the code you posted is somewhat ugly. I wouldn't say it's clear. It's a kind of a hack. So if using some other coding solution would be worse, then ok. But if you have better alternative, don't let the excuse "it's good enough" comfort you.
Its a very strange idiom. It uses a loop for something its not intended and may cause confusion. I'd imagine this is going to span more than one page, and it would be a surprise to most people that this is never run more than once.
How about using more usual language features like functions?
bool success = someSensibleFunctionName();
if(success)
{
...
}
someCommonCodeInAnotherFunction();
I would consider this bad practice. I think it would be more idiomatic, and generally clearer if you made this a function and changed the breaks to returns.
Split your code into smaller chunks of functional elements - so you could split the above into a function that returns instead of breaking.
I don't know if the above is bad practice but it's readability is a little off and may be confusing to others who might have to maintain the source.
To me what you are doing is bad in so many ways. The loop can be replaced by putting that code in a method.
I personally believe that if you have to put a ! in front of your conditions then you are looking for the wrong thing. For readability make your boolean match what you are checking for. You are really checking if there is an error or some bad condition, so I would prefer:
If (isError)
{
//Do whatever you need to do for the error and
return;
}
over
If (!isGood)
{
//Do something
}
So check for what you really want to check for and keep the exception checks to a minimum. Your goal should be readibility over being tricky. Think of the poor soul that is going to have to come along and maintain your code.
One of the first things I worked on 28 years ago was a Fortran program that always needed to check if there was a graphics device available. Someone made the grand decision to call the boolean for this LNOGRAF, so if there was a graphics device available this would be false. I believe it got set this way because of a false efficiency, the check for the device returned zero if there was a graphics device. Throughout the code all the checks were to see if the graphics device was available. It was full of:
If (.NOT. LNOGRAF)
I don't think there was a single:
If (LNOGRAF)
in the program. This was used in mission planning software for B-52's and cruise missiles. It definitely taught me to name my variables for what I'm really checking for.
What about a functional approach?
void method1()
{
... some code
if( condition )
method2();
}
void method2()
{
... some more code
if( condition )
method3();
}
void method3()
{
... yet more code
if( condition )
method4();
}
I would say your solution can be the right solution, but it depends. Paul Tomblin has posted an answer that is better (a series of if tubes) ... if it can be used.
Paul's solution cannot be used when there are expensive object initializations along the way through your loop. If the created objects are used in later steps, the do while (0) solution is better.
That said, variable naming should be improved. Additionally, why reuse the "escape" variable so much? Instead trap each individual error condition explicitly and break the loop so that it is obvious what causes the break out at each point.
Someone else suggested using function calls. Again, this may not be an ideal decomposition if it adds unneeded complexity to the function calls due to the number of args that might be passed at any given step.
Others have suggested this is a difficult to understand idiom. Well, first you could put a comment as suggested at the top of the loop. Second, do-while(0) is a normal and common idiom in macros that all C programmers should recognize immediately, so I just don't buy that.
If your code is doing something other than the plain meaning of the constructs in place, it's a good sign you've ventured into "cute" territory.
In this case you have a "loop" that will only run once. Any reader of the code will need to do a double-take to figure out what's going on.
If the case where it isn't "good" is truly exceptional, then throwing exceptions would be the better choice.
First, if you just want an answer to whether this code structure or idiom is "bad", I would think it is. However, I think this is a symptom of bad decomposition rather than whether the code you have is "good" or "bad".
I would think much better analysis and refactoring will have to be done to be able to further address the source of the problem, rather than looking just at the code. If you can do something like:
if (condition1(...) && condition2(...) && condition3(...) && ... && conditionN(...)) {
// code that ought to run after all conditions
};
// code that ought to run whether all conditions are met or not
Then I think it would be more "readable" and more idiomatic. This way, you can make functions like:
bool conditionN(...) {
if (!real_condition) return false;
// code that ought to run
return true;
};
You get the benefit of better decomposition and help from the compiler to produce the necessary short-circuitry that &&'s will bring. The compiler might even in-line the code in the functions to produce better code than if you would doing the hand-coded loop.
You can use exceptions for that, but exceptions generally are not recommended in normal application logic, only for abnormal situations.
Nothing's wrong with using exceptions. Exceptions are part of application logic. The guideline about exceptions is that they should be relatively rare at run time.
I think that there is nothing basically wrong with the technique. I think that I would make sure that the bool is named something more descriptive than isGood. Although, now that I look at it, why would it not work to put all the code that is in the loop into a single if(!isGood) block? The loop only executes once.
If splitting code between if(!isGood) break; into separate functions, one can end up with dozens of functions containing of just a couple of lines, so that doers not simplify anything. I could not use return because I am not ready to leave the function, there is still stuf I want to do there.
I accept that probably I should just settle for separate if(isGood) {...} condition for every code part which I want to execute, but sometimes that would lead to A LOT of curly braces. But I guess I accept that people does not really like that type of construction, so conditions for everything winds! Thanks for your answers.
A meta comment:
When you're coding, your goal should be clear, maintainable code first. You should not give up legibility on the altar of efficiency unless you profile and prove that it is necessary and that it actually improves things. Jedi mind tricks should be avoided. Always think that the next guy to maintain your code is a big mean psychopath with your home address. Me, for instance.
I think I'd have to agree with your colleagues just because of readability, it's not clear atfirst glance what you are trying to accomplish with this code.
Why not just use
if(isGood)
{
...Execute more code
}
?
I think people aren't being honest here.
If I, as your team lead, would see code like this you'd be up for a little one on one, and flagged as a potential problem for the team as that piece of code is particularly horrid.
I say you should listen to your colleagues and rewrite it following any of the suggestions posted here.
This is what exceptions are for. You can't continue the logic because something went wrong. Even if recovery is trivial, it is still an exception. If you have a really good reason for not using exceptions, such as when you program in a language that does not support them, then use conditional blocks, not loops.

In C++ what are the benefits of using exceptions and try / catch instead of just returning an error code?

I've programmed C and C++ for a long time and so far I've never used exceptions and try / catch. What are the benefits of using that instead of just having functions return error codes?
Possibly an obvious point - a developer can ignore (or not be aware of) your return status and go on blissfully unaware that something failed.
An exception needs to be acknowledged in some way - it can't be silently ignored without actively putting something in place to do so.
The advantage of exceptions are two fold:
They can't be ignored. You must deal with them at some level, or they will terminate your program. With error code, you must explicitly check for them, or they are lost.
They can be ignored. If an error can't be dealt with at one level, it will automatically bubble up to the next level, where it can be. Error codes must be explicitly passed up until they reach the level where it can be dealt with.
The advantage is that you don't have to check the error code after each potentially failing call. In order for this to work though, you need to combine it with RAII classes so that everything gets automatically cleaned up as the stack unwinds.
With error messages:
int DoSomeThings()
{
int error = 0;
HandleA hA;
error = CreateAObject(&ha);
if (error)
goto cleanUpFailedA;
HandleB hB;
error = CreateBObjectWithA(hA, &hB);
if (error)
goto cleanUpFailedB;
HandleC hC;
error = CreateCObjectWithA(hB, &hC);
if (error)
goto cleanUpFailedC;
...
cleanUpFailedC:
DeleteCObject(hC);
cleanUpFailedB:
DeleteBObject(hB);
cleanUpFailedA:
DeleteAObject(hA);
return error;
}
With Exceptions and RAII
void DoSomeThings()
{
RAIIHandleA hA = CreateAObject();
RAIIHandleB hB = CreateBObjectWithA(hA);
RAIIHandleC hC = CreateCObjectWithB(hB);
...
}
struct RAIIHandleA
{
HandleA Handle;
RAIIHandleA(HandleA handle) : Handle(handle) {}
~RAIIHandleA() { DeleteAObject(Handle); }
}
...
On first glance, the RAII/Exceptions version seems longer, until you realize that the cleanup code needs to be written only once (and there are ways to simplify that). But the second version of DoSomeThings is much clearer and maintainable.
DO NOT try and use exceptions in C++ without the RAII idiom, as you will leak resources and memory. All your cleanup needs to be done in destructors of stack-allocated objects.
I realize there are other ways to do the error code handling, but they all end up looking somewhat the same. If you drop the gotos, you end up repeating clean up code.
One point for error codes, is that they make it obvious where things can fail, and how they can fail. In the above code, you write it with the assumption that things are not going to fail (but if they do, you'll be protected by the RAII wrappers). But you end up paying less heed to where things can go wrong.
Exception handling is useful because it makes it easy to separate the error handling code from the code written to handle the function of the program. This makes reading and writing the code easier.
return an error code when an error condition is expected in some cases
throw an exception when an error condition is not expected in any cases
in the former case the caller of the function must check the error code for the expected failure; in the latter case the exception can be handled by any caller up the stack (or the default handler) as is appropriate
Aside from the other things that were mentioned, you can't return an error code from a constructor. Destructors either, but you should avoid throwing an exception from a destructor too.
I wrote a blog entry about this (Exceptions make for Elegant Code), which was subsequently published in Overload. I actually wrote this in response to something Joel said on the StackOverflow podcast!
Anyway, I strongly believe that exceptions are preferable to error codes in most circumstances. I find it really painful to use functions that return error codes: you have to check the error code after each call, which can disrupt the flow of the calling code. It also means you can't use overloaded operators as there is no way to signal the error.
The pain of checking error codes means that people often neglect to do so, thus rendering them completely pointless: at least you have to explicitly ignore exceptions with a catch statement.
The use of destructors in C++ and disposers in .NET to ensure that resources are correctly freed in the presence of exceptions can also greatly simplify code. In order to get the same level of protection with error codes you either need lots of if statements, lots of duplicated cleanup code, or goto calls to a common block of cleanup at the end of a function. None of these options are pleasant.
Here's a good explanation of EAFP ("Easier to Ask for Forgiveness than Permission."), which I think applies here even if it's a Python page in Wikipedia. Using exceptions leads to a more natural style of coding, IMO -- and in the opinion of many others, too.
When I used to teach C++, our standard explanation was that they allowed you to avoid tangling sunny-day and rainy-day scenarios. In other words, you could write a function as if everything would work ok, and catch the exception in the end.
Without exceptions, you would have to get a return value from each call and ensure that it is still legitimate.
A related benefit, of course, is that you don't "waste" your return value on exceptions (and thus allow methods that should be void to be void), and can also return errors from constructors and destructors.
Google's C++ Style Guide has a great, thorough analysis of the pros and cons of exception use in C++ code. It also indicates some of the larger questions you should be asking; i.e. do I intend to distribute my code to others (who may have difficulty integrating with an exception-enabled code base)?
Sometimes you really have to use an exception in order to flag an exceptional case. For example, if something goes wrong in a constructor and you find it makes sense to notify the caller about this then you have no choice but to throw an exception.
Another example: Sometimes there is no value your function can return to denote an error; any value the function may return denotes success.
int divide(int a, int b)
{
if( b == 0 )
// then what? no integer can be used for an error flag!
else
return a / b;
}
The fact that you have to acknowledge exceptions is correct but this can also be implemented using error structs.
You could create a base error class that checks in its dtor whether a certain method ( e.g. IsOk ) has been called. If not, you could log something and then exit, or throw an exception, or raise an assert, etc...
Just calling the IsOk on the error object without reacting to it, would then be the equivalent of writing catch( ... ) {}
Both statement would display the same lack of programmer good will.
The transport of the error code up to the correct level is a greater concern. You would basically have to make almost all methods return an error code for the sole reason of propagation.
But then again, a function or method should always be annotated with the exceptions it can generate. So basically you have to same problem, without an interface to support it.
As #Martin pointed out throwing exceptions forces the programmer to handle the error. For example, not checking return codes is one of the biggest sources of security holes in C programs. Exceptions make sure that you handle the error (hopefully) and provide some kind of recover path for your program. And if you choose to ignore an exception rather than introduce a security hole your program crashes.