From: Goran on
On Jun 22, 9:14 pm, "Doug Harrison [MVP]" <d...(a)mvps.org> wrote:
> On the API designer side, using
> exceptions where return codes are more appropriate forces callers to write
> try/catch whenever they use the function, so that's a bad use of
> exceptions.

Hey! Tell that to designers of APIs like VCL of Borland or .NET,
then ;-).

On a more serious note... .NET almost exclusively uses exceptions to
report errors and I am aware of one place where, over the time, they
decided to revert to having a non-throwing variant of the function
(TryParse wasn't there in initial .NET versions).

> You never want to turn exception usage into a clumsier version
> of return codes.

That is true. What I wanted to say, I guess, is that even API design
goes well with exceptions, and APIs where it is interesting to have
error-return seem rarer than what one might think from your post.

Goran.
From: Goran on
On Jun 22, 11:06 pm, "David Ching" <d...(a)remove-this.dcsoft.com>
wrote:
> "Doug Harrison [MVP]" <d...(a)mvps.org> wrote in messagenews:9c1226ldk8g207f4asif27nehrcfji6g0e(a)4ax.com...
>
>
>
> > On Tue, 22 Jun 2010 13:12:33 -0400, Joseph M. Newcomer
> > <newco...(a)flounder.com> wrote:
>
> >>I'm not sure this is a good piece of advice.  I use try/catch a lot; it is
> >>essentially a
> >>"non-local GOTO", a structured way of aborting execution and returning to
> >>a known place,
> >>while still guaranteeing that all intermediate destructors for stack
> >>variables are called.
> >>It is particularly useful in writing tasks like recursive-descent parsers
> >>(particularly if
> >>you just want to stop without trying to do error recovery, which is always
> >>hard) and
> >>terminating threads while still guaranteeing that you return from the
> >>top-level thread
> >>function.  It is  clean and well-structured way of aborting a
> >>partially-completed
> >>operation.  An it is the only way to report errors from operations like
> >>'new'.  Also, look
> >>at the number of exceptions that can be thrown by std:: or boost::.
>
> > Goran was not saying exceptions are bad, just that overly frequent use of
> > try/catch is bad, which it usually is. I've been saying for a long long
> > time that there's an inverse relationship between the number of try/catch
> > clauses you have and the effectiveness with which you're using exceptions.
> > There are a number of reasons for this. On the API designer side, using
> > exceptions where return codes are more appropriate forces callers to write
> > try/catch whenever they use the function, so that's a bad use of
> > exceptions. You never want to turn exception usage into a clumsier version
> > of return codes. On the user side, try/catch gets overused when people
> > don't employ the RAII idiom and need to perform clean-up that should be
> > handled by a destructor. Ideally, exceptions are caught far away from
> > where
> > they're thrown, in a top-level handler, which reports the error to the
> > user, logs it, or whatever. It is relatively rare for well-designed code
> > to
> > need to handle the exception closer to the throw-point.
>
> Not to mention, the overhead of throwing exceptions reduces performance if
> many exceptions are thrown.

I am sorry, I have to press you here. When did you have performance
issues because of that? The thing is, if there's too many exceptions
thrown, there is something wrong with the design. Also, if there
indeed is too many of them, chances are that the code doesn't work
anyhow. If that's the case, does it really matter how fast (or slow)
it doesn't work? You need e.g. some multithreaded code where some
threads eat up too much time because it doesn't work at all and throws
exceptions in a loop.

IOW, situations where one will be concerned about performance aspect
of exceptions are much rarer than one might think from your post. ( I
am getting annoying with this, aren't I? :-( )

Goran.
From: Goran on
On Jun 23, 1:49 am, Joseph M. Newcomer <newco...(a)flounder.com> wrote:
> Key here is how much you have to do in the catch.  Putting all the recovery code in the
> catch would consolidate it and eliminate that horror of "goto exit" that happens so often.

Hey, +1 for this.

goto is for me forbidden in C++ (but arguably the best approach for
the likes of C).

Goran.
From: Giovanni Dicanio on
On 23/06/2010 01:51, Joseph M. Newcomer wrote:

> Note that this could be handled as
>
> BOOL TryParse(...args...)
> {
> try
> {
> Parse(...);
> return TRUE;
> }
> catch(..whatever..)
> {
> return FALSE;
> }
> }
>
> It ain't rocket science. And it isn't clear to me how handling the exception results in
> "bad code".

Sure it isn't (ain't?) rocket science... but do you like a fopen that
throws an exception if the file cannot be opened? No, I prefer one
returning an error code.
The fact that you can't open a file is not an exceptional condition, and
I prefer code like:

if ( some_open_file_api(...) == error )
{
... do what you want... (e.g. create the file, or other stuff...)
}
... normal flow

instead of try/catch.

It was clearly written before: the usefulness of exceptions is inversely
proportional to the number of try/catch you use: if you clutter your
code with lots of try/catch then IMHO you are overusing (abusing)
exceptions.

I think exceptions should be used in *exceptional* conditions (like
David wrote before).


BTW: I like these articles from the OldNewThing blog:

"Cleaner, more elegant, and wrong"
http://blogs.msdn.com/b/oldnewthing/archive/2004/04/22/118161.aspx

"Cleaner, more elegant, and harder to recognize"
http://blogs.msdn.com/b/oldnewthing/archive/2005/01/14/352949.aspx


Giovanni

From: Giovanni Dicanio on
On 23/06/2010 06:17, David Ching wrote:

> Joe, all I know is the MS architects felt adding TryParse() was
> necessary in .NET 2.0 due to the overhead of Parse() throwing
> exceptions. You can take it up with them.

I do agree with the addition of TryParse:


"Vexing exceptions"

http://blogs.msdn.com/b/ericlippert/archive/2008/09/10/vexing-exceptions.aspx

<quote>

Vexing exceptions are the result of unfortunate design decisions. Vexing
exceptions are thrown in a completely non-exceptional circumstance, and
therefore must be caught and handled all the time.

The classic example of a vexing exception is Int32.Parse, which throws
if you give it a string that cannot be parsed as an integer. But the 99%
use case for this method is transforming strings input by the user,
which could be any old thing, and therefore it is in no way exceptional
for the parse to fail. Worse, there is no way for the caller to
determine ahead of time whether their argument is bad without
implementing the entire method themselves, in which case they wouldn't
need to be calling it in the first place.

This unfortunate design decision was so vexing that of course the
frameworks team implemented TryParse shortly thereafter which does the
right thing.

You have to catch vexing exceptions, but doing so is vexing.

Try to never write a library yourself that throws a vexing exception.

</quote>


Giovanni