|
Wolfgang_Baron wrote: They both complicate the flow of control. In fact, people used to do long jumps (non local gotos) to do some of the things people use exceptions for these days. Exceptions "complicate" the flow in a well defined way while gotos can be used to break the flow in a lot of unexpected/buggy ways (like jumping into a for loop without running its pre-init expression, jumping back, here and there). If you think that exceptions complicate the flow then you are simply not familiar with exception handling. Exceptions centralize error handling and by separating code that does the actual work and the code that handles errors it makes the flow much cleaner and the source becomes easier to read and there is no silently unhandled error (that would be a bug). The flow is much cleaner, in case of successful execution its basically linear and in case of error its a lot of automatic multiple returns (with the execution of some cleanup finally blocks) that is the usual thing someone wants in case of error.
Wolfgang_Baron wrote: you are not obliged to use a language feature, just because the language has it In a language where exception handling is a core mechanism (C#, java, python, ...) The whole standard library returns errors in the form of exceptions. You can't do a small step (like opening/writing/closing a file) without having to handle exceptions. In java with checked exceptions you are even more forced to handle them. In modern languages exception usage is not a choice. In C++ where most libs (even stl) can operate without exceptions its a choice.
|
|
|
|
|
pasztorpisti wrote: If you think that exceptions complicate the flow then you are simply not familiar with exception handling.
If you are not familiar with the code complexity caused by the usage of exceptions, then you are simply not familiar with exception handling and software analysis. Maybe you have that cool, bullet proof software analysis tool, which tells you, what happens behind the scenes and in which places things can happen, which you would not expect. Please tell us about it.
To trace the usage of exceptions, compilers would have to make use of exception specifications, which even Visual C++ does not, as you can read on http://msdn.microsoft.com/en-us/library/wfa0edys.aspx[^]. It's either "the function throws nothing" or "the function may throw anything", which just ruins your day.
As I said, I like the concept of exceptions, but in real life, given the current support by programming tools, the costs usually outweigh the benefits. Code, which I had to refactor, because exceptions were not allowed always came out easier to understand and easier to reason about and thus faster and safer to modify, extend or otherwise maintain.
pasztorpisti wrote: In a language where exception handling is a core mechanism (C#, java, python, ...) The whole standard library returns errors in the form of exceptions. ...
Wolfgang_Baron wrote: If you are forced to incorporate code, that makes use of exceptions, you will, of course, have to deal with them.
All right, as I am starting to answer your quotes with my quotes, I will stop answering your never ending praise for your counterproductive programming practices (which I used to practice too, until I discovered, that it did not serve me well). You can either try out my advice or just stick to whatever you did before. I have no problem with that.
|
|
|
|
|
So you are saying that programming in C# or Java, Delphi, python, ... is counterproductive? I wouldn't think so, exception handling has been chosen as an error handling mechanism in these languages with a reason. The extreme static analyzation you are talking about is quite rarely needed in practice: in case of some embedded devices (that are usually programmed in C and this language is primitive engough to be relatively easy to analyze). There are some other fields where software has to be "theoretically correct" and bug free like in case of financial auto-traders. A lot of companies that do this are using haskell that has superb static analyzer tools and the code is automatically free of side-effect related bugs and is a good candidate for easy to parallelization.
Even if a piece of software has to be statically analyzed, thrown exceptions for functions are much well defined in modern languages and exceptions affect only a few analyzation techniques. In C++ exception handling is not too well defined/designed. Static analyzation is not a good excuse for not using exceptions. Exceptions may make the work for a static analyzer harder but they make the work for a programmer much easier and while a static analyzer has to be written only once, programmers write much more code with the aid of exceptions. Besides this exceptions affect only a set of the features of a static analyzers.
We regularly run a static analyzer on our C++ codebase (every month) but its much worse (even without using exceptions) than a static analyzer for a modern language that has a reason: C++ is very hard to parse language with full of heritage features and not well designed exception handling mechanism. It is a very hard to analyze in contrast to a modern language including the flow control induced by exception handling. I've used static analyzers for java too and they were much more reliable and better than any analyzer for C++ despite the fact that exception handling is a very core feature of java. If exceptions are well defined then the possible flows of control can be tracked very well by an analyzer. I wouldn't compare the usability and reliability of C++ dev tools to that of java or C# tools and the only reason is the unnecessary complexity of C/C++ that accumulated through the years.
|
|
|
|
|
Wolfgang_Baron wrote: The usage of exceptions is another hot topic we probably can talk about for ages ...
"Mechanically" exceptions behave like "multiple implicit returns" that jump into the nearest exception handler by executing all finally/RAII blocks on the way. If a program (or used library) is written with exception handling then you can forget about single point of return if you don't want to catch all exceptions including those that you can't handle. This is a point where your theory about using single point of return really fails. Previous this never came to my mind... BTW, do you use modern languages and exceptions at all?
|
|
|
|
|
Ah, you are so predictable , so here we go ...
In fact, I have always been very fond of exceptions. It's a nice idea and you can construct situations, where the could really appear to simplify your code. In reality, I never found a program, where they really were worth the trouble. Here are some downsides:
- in an evolving program, you really never stay in control of what code jumps where in which situations. With a lot of discipline you may construct a nicely working program using exceptions. After changing it for a while, you will notice, that exceptions are thrown in places, where you can't use them. So you have to get that under control with even more discipline. A watertight analysis tool would make this a lot easier, but I have not found one yet
- as you have noticed yourself, exceptions introduce something like multiple exits, making the analysis, what your program really does a lot harder
- trying to verify post conditions for methods or functions gets incredibly complicated, probably causing the quality of your code to degrade
- using exceptions is not compatible with common, modern programming models like event driven software
- exceptions work badly in multi threaded applications
- exceptions ruin the usage of RPC etc.
- exceptions slow down your code and unnecessarily increase its size
- safety critical software (avionics, cars, defense etc.) forbid exceptions (and they know what they are doing and why they are doing it)
- find more pros and cons at http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml?showone=Exceptions#Exceptions[^]
That being said, there are of course nice things to say about exceptions and my point of view is, that you have to be ready to handle them (e.g. in constructors, dynamic allocations etc.) but use them with caution.
|
|
|
|
|
Wolfgang_Baron wrote: Ah, you are so predictable , so here we go ... This is a technical forum and besides this after exchanging a few posts I think we should avoid being personal. Could you please concentrate on the technical stuff?
Wolfgang_Baron wrote: - in an evolving program, you really never stay in control of what code jumps where in which situations. With a lot of discipline you may construct a nicely working program using exceptions. After changing it for a while, you will notice, that exceptions are thrown in places, where you can't use them. So you have to get that under control with even more discipline. A watertight analysis tool would make this a lot easier, but I have not found one yet
- as you have noticed yourself, exceptions introduce something like multiple exits, making the analysis, what your program really does a lot harder
- trying to verify post conditions for methods or functions gets incredibly complicated, probably causing the quality of your code to degrade
- using exceptions is not compatible with common, modern programming models like event driven software
- exceptions work badly in multi threaded applications
- exceptions ruin the usage of RPC etc. Not true. Ask if you are interested my opinion in one of these points.
Wolfgang_Baron wrote: - exceptions slow down your code and unnecessarily increase its size Partly true, table driven exceptions slow you down only in case of actually thrown exceptions that happens rarely in some programs that use this to indicate errors (like IOExcpeption). Besides this, most programs are not performance critical and the advantages you gain with exception handling outweigh the disadvantages by far.
Wolfgang_Baron wrote: - safety critical software (avionics, cars, defense etc.) forbid exceptions (and they know what they are doing and why they are doing it) Not only safety critical software, the largest codebase I'm currently working on forbids exceptions because it is extremely performance critical, but again, this is a problem only in case of the minority of applications. Exceptions are forbidden because of a requirement/technical limitation and not because they wouldnt be able to make the source code and error handling better.
Facts:
- Some languages (C#, java, python, ...) use exceptions and force you to use exceptions to handle errors at their core. The libraries are using exceptions so you have to handle them. In C++ some software and a lot of libraries don't use it (probably because a lot of these libs are rather C libs written by C programmers). Do you work with any modern languages?
- Most applications are simply not performance critical and having a clean and easy-to-maintain source code is the most important. Exception handling helps in that, helps in centralizing error handling, makes sure that errors are not ignored (!!!) and chained exceptions/stacktraces are extremely helpful in locating errors (!!!) even in RPC/networking programs -> stacktraces and chained exceptions can flow over networks from the server to the client and vice versa!!! (Ruins the usage of RPC??? Ridiculous, have you ever used networking/rmi in java or the same in C#???)
- What do you think, why is exception handling a core feature of a lot of modern general purpose programming languages? (C#, Java, ...)
- I don't need to read pros and cons because I've already read enough and besides this I have my own opinions too and I'm happy to discuss the advantages and disadvantages. Fact: Sometimes the advantages simply outweigh the disadvantages. This is a general truth, most decisions balance between advantages and disadvantages especially in case of programming.
Wolfgang_Baron wrote: That being said, there are of course nice things to say about exceptions and my point of view is, that you have to be ready to handle them (e.g. in constructors, dynamic allocations etc.) but use them with caution. Anything can be abused (even a simple if statement). A knife is a nice tool until you start cutting your own fingers with it...
|
|
|
|
|
Reason for my vote of 5
The first alternate is the most readable and robust way to do this. I always use this method.
|
|
|
|
|
Reason for my vote of 5
IMHO the superior technique. I don't want to use a construct for other than its intended purpose, be it a loop or an exception.
|
|
|
|
|