Exception Misconceptions: Exceptions are for unrecoverable errors.

D

dragan

Saying "Exceptions are for unrecoverable errors" seems to imply that they
are to be used only or mostly in such situations. Whereas the exception
machinery in C++ was developed primarily to handle and RECOVER from more
errors more elegantly than was possible without exceptions, the statement is
highly suspect. Those "unrecoverable errors" are probably the things that
assertion checking weeds out during development time rather than being an
application for exception machinery. "Unrecoverable error": throw up a
dialog for the developer and exit (or crash to keep the call stack in view
in the debugger). Exceptions, are more appropriately used where there is a
likelihood of recovering from the error condition rather than being just for
"unrecoverable errors". Futher discussion of the application of exceptions
is appreciated. Keep in mind that while there are SOME general vague
"principles" of the application of exceptions, mostly the scenarios need to
be defined for fruitful discussion. Please keep the examples simple but
realistic and note the assumptions you make.
 
A

Alf P. Steinbach

* dragan:
Saying "Exceptions are for unrecoverable errors" seems to imply that they
are to be used only or mostly in such situations. Whereas the exception
machinery in C++ was developed primarily to handle and RECOVER from more
errors more elegantly than was possible without exceptions, the statement is
highly suspect.
Yes.


Those "unrecoverable errors" are probably the things that
assertion checking weeds out during development time rather than being an
application for exception machinery. "Unrecoverable error": throw up a
dialog for the developer and exit (or crash to keep the call stack in view
in the debugger). Exceptions, are more appropriately used where there is a
likelihood of recovering from the error condition rather than being just for
"unrecoverable errors".

C++ unfortunately lacks any concept exceptions that won't be caught by ordinary
catch(...). Therefore, in current C++ you should preferentially not use
exceptions for unrecoverable failures, not to speak of unrecoverable errors!
Just log and terminate.

Futher discussion of the application of exceptions
is appreciated. Keep in mind that while there are SOME general vague
"principles" of the application of exceptions, mostly the scenarios need to
be defined for fruitful discussion. Please keep the examples simple but
realistic and note the assumptions you make.

Hm, I failed to see the question in there, sorry.


Cheers & hth.,

- Alf
 
S

Stefan Ram

dragan said:
Saying "Exceptions are for unrecoverable errors" seems to
imply that they are to be used only or mostly in such
situations.

BTW: Who did actually say this?
Whereas the exception machinery in C++ was developed
primarily to handle and RECOVER from more errors more
elegantly than was possible without exceptions, the statement
is highly suspect.

More elegantly? Actually, for correct and secure C++ code,
all functions need to be written to be »exception safe«, but
only a minority of C++ programmers does so or even is aware
of it.
Those "unrecoverable errors" are probably the things that
assertion checking weeds out during development time rather
than being an application for exception machinery.

These are distinct concepts for me: An unrecoverable error
can occur when a program needs 10 Bytes of allocated
storage, but this storage is not available. The program can
not generate more storage, so the error is not recoverable,
but it also can not be weeded out during developement time.
Futher discussion of the application of exceptions is
appreciated.

I prefer error results to exceptions. So all I would write
about exceptions would start with »If I was forced to use a
language that would force me to use exceptions ...«

The applications of error results is as follows:

if( attempt( to_do_something ))
{ case 0: /* ok, continue */ ... break;
case 1: /* oops, handle */ ... break;
... }
 
V

Vladimir Jovic

Stefan Ram wrote:
[snip]
More elegantly? Actually, for correct and secure C++ code,
all functions need to be written to be »exception safe«, but
only a minority of C++ programmers does so or even is aware
of it.

Why?
I thought only the code in the catch blocks have to be exception safe.
Might be new exception misconception ;)

[snip]
I prefer error results to exceptions. So all I would write
about exceptions would start with »If I was forced to use a
language that would force me to use exceptions ...«

The applications of error results is as follows:

This should have probably been "switch" instead of "if" :
if( attempt( to_do_something ))
{ case 0: /* ok, continue */ ... break;
case 1: /* oops, handle */ ... break;
... }

Back to return value vs exceptions.

1)
What happens if you can not handle the error in this method?
Or in the method that called this method?
Or in the method that called the method that called the method where the
error happened?
etc

2) How do you handle errors in constructors?

3) Simple example : how would you create a method (or a function) that
reads a value (some random integer) from a file and returns that value?
 
S

Stefan Ram

Vladimir Jovic said:

Read any text about exception safety in C++.
This should have probably been "switch" instead of "if" :

Yes, thank you.
What happens if you can not handle the error in this method?

I define »handle« to be whatever measures are appropriate
for »me« (=»the current method«) to take in this case.
By this definition I can always handle an error.
2) How do you handle errors in constructors?

Well, I see and know that C++ nearly forces me to use
exceptions in constructors. However, to avoid this, I could
use the following style whenever I can control a class
(but I do not say that I recommend this for C++):

windowattempt attempt( 640, 480 ); /* "windowattempt" is a class. */
window * window; /* "window" is a class, too. */
if( attempt.succeeded() )
{ window = attempt.getwindow(); }
else
{ switch( attempt.error() )
{ ...
3) Simple example : how would you create a method (or a function) that
reads a value (some random integer) from a file and returns that value?

/* "filereader" is an object */
int const value = filereader.nextint();
if( filereader.error() ) /* handle this */ ...
else /* continue */ ...
 
K

Kaz Kylheku

Stefan Ram wrote:
[snip]
More elegantly? Actually, for correct and secure C++ code,
all functions need to be written to be »exception safe«, but
only a minority of C++ programmers does so or even is aware
of it.
Why?

The above is false. Exception-safe code is needed to write code
that avoids resource leaks in the face of an exception.

For instance:

{
char *p = new char[256];
f();
}

If f throws an exception, this statement block is abandoned, and the
allocated memory is leaked. Of course other kinds of resources can be
leaked, like handles to operating system resources such as open files.

Leaking a resource is not automatically incorrect. Firstly, it does not
violate any C++ language rule. Allocating memory and losing the pointer
does not trigger undefined behavior. Whether it is an issue or not
depends on the precise situation in which it occurs. Many C++ programs
leak resources by design simply because they lose references to objects
when terminating by returning via main. This doesn't matter if the
operating system cleans up the resources after a program that
terminated. Minor resource leaks in short-lived programs are often not a
problem.

Leaking resource is not necessarily a security problem, either. Firstly,
there isn't any way it can grant an attacker the ability to execute
arbitrary code. At worst, a leak can be exploited to launch a
denial-of-service attack. To exploit a leak which occurs during an
exception, the attacker has to figure out how to get the program to
throw that exception, and moreover, to do it over and over again to
exhaust the available resources. If the exception is fatal, it doesn't
matter; the attacker gets to tickle it once, and the program is gone.

The exception has to be used as an indication of some non-fatal situation
that the attacker can create at will. E.g. suppose that a password
entry prompt uses an exception to indicate that the password was not
accepted. The attacker then simply has to keep trying incorrect
passwords to repeat the leak.
Back to return value vs exceptions.

1)
What happens if you can not handle the error in this method?
Or in the method that called this method?
Or in the method that called the method that called the method where the
error happened?
etc

Then you have to keep returning an indication to the caller. The easiest
way to do this is to consistently adhere to a single convention for
error indication throughout the entire program.

A good example of this technique is the Linux kernel.
2) How do you handle errors in constructors?

You set a ``successfully constructed'' flag in the object which is
tested after construction, through some public member function.
3) Simple example : how would you create a method (or a function) that
reads a value (some random integer) from a file and returns that value?

There are a few ways. One is to store the integer via a pointer or
reference parameter and return the success/error indication.
 
D

dragan

Stefan Ram said:
BTW: Who did actually say this?

Someone in c.l.c++.m said something like what is in quotes above (pretty
much exactly). I got the thus-far-presented misconceptions from that NG.
 
D

dragan

Alf P. Steinbach said:
* dragan:

Hm, I failed to see the question in there, sorry.

That there were no question marks in the entire OP means there were no
questions in it. For your reference, this is what a question mark looks
like: ?

;)
 
D

dragan

Alf P. Steinbach said:
* dragan:

Hm, I failed to see the question in there, sorry.

That there were no question marks in the entire OP means there were no
questions in it. For your reference, this is what a question mark looks
like: ?

;)
 
T

tanix

* dragan:


C++ unfortunately lacks any concept exceptions that won't be caught by ordinary

catch(...). Therefore, in current C++ you should preferentially not use
exceptions for unrecoverable failures, not to speak of unrecoverable errors!
Just log and terminate.

In Java, there is a separation betwen exceptions and errors.

Exceptions could be used on a very fine grained level, such
as numeric string parsing, and in case there is a non digit
present, you simply catch the exception and replace the
result with default value. Works like a champ.
In fact, you MUST use try/catch block to do these conversion.
Otherwise, your code won't even compile.

With error, you are dead. You can not even recover from them.
Hm, I failed to see the question in there, sorry.

Some people just feel they need to dominate, like THEIR word
is "the word of God". They tend to fail to comprehend that
THEIR view is just that, THEIR view. Nothing more than that.
Cheers & hth.,

--
Programmer's Goldmine collections:

http://preciseinfo.org

Tens of thousands of code examples and expert discussions on
C++, MFC, VC, ATL, STL, templates, Java, Python, Javascript,
organized by major topics of language, tools, methods, techniques.
 
T

tanix

That there were no question marks in the entire OP means there were no
questions in it. For your reference, this is what a question mark looks
like: ?
Impressive.

;)


--
Programmer's Goldmine collections:

http://preciseinfo.org

Tens of thousands of code examples and expert discussions on
C++, MFC, VC, ATL, STL, templates, Java, Python, Javascript,
organized by major topics of language, tools, methods, techniques.
 
T

tanix

BTW: Who did actually say this?


More elegantly? Actually, for correct and secure C++ code,
all functions need to be written to be »exception safe«,

Correct.
Almost everything you do will generate some kind of exception,
at least in modern languages, and it is good it does.
but
only a minority of C++ programmers does so or even is aware
of it.


These are distinct concepts for me: An unrecoverable error
can occur when a program needs 10 Bytes of allocated
storage, but this storage is not available. The program can
not generate more storage, so the error is not recoverable,
but it also can not be weeded out during developement time.


I prefer error results to exceptions. So all I would write
about exceptions would start with »If I was forced to use a
language that would force me to use exceptions ...«

The applications of error results is as follows:

if( attempt( to_do_something ))
{ case 0: /* ok, continue */ ... break;
case 1: /* oops, handle */ ... break;
... }

Well, there are two styles of coding.
One is: as soon as you can return the correct result,
return it.

If you ever get to code that was past the end of all
your good returns, everything you are dealing with
from then on is errors.

The second style is just the opposite:
Handle all errors first. When you handled ALL of them,
and I mean ALL, then you are home free.

These two approaches define your logic eventually.
It is quite a different logic.

With 2nd approach, you tend to get a more robust code
because it forces you to think about all sorts of problems,
you may not pay attention to otherwise.

--
Programmer's Goldmine collections:

http://preciseinfo.org

Tens of thousands of code examples and expert discussions on
C++, MFC, VC, ATL, STL, templates, Java, Python, Javascript,
organized by major topics of language, tools, methods, techniques.
 
T

tanix

Stefan Ram wrote:
[snip]
More elegantly? Actually, for correct and secure C++ code,
all functions need to be written to be »exception safe«, but
only a minority of C++ programmers does so or even is aware
of it.

Why?
I thought only the code in the catch blocks have to be exception safe.
Might be new exception misconception ;)

The code in your catch block is not necessarily exception safe.
It all depends what are you going to do to recover from the
original exception. You MAY get yet another exception when
trying to recover from the original one.

In some places in my code, I have nested exceptions.
Acutlly in quite a few MOST important places.
That is why this thing runs like a tank.
You can just turn the power switch on in the middle of the
most important and critical and time consuming operation.
[snip]
I prefer error results to exceptions. So all I would write
about exceptions would start with »If I was forced to use a
language that would force me to use exceptions ...«

The applications of error results is as follows:

This should have probably been "switch" instead of "if" :
if( attempt( to_do_something ))
{ case 0: /* ok, continue */ ... break;
case 1: /* oops, handle */ ... break;
... }
Back to return value vs exceptions.

1)
What happens if you can not handle the error in this method?

Correct, and it is not such an uncommon thing.
Because, first of all, the error is local.
Your routine does not necessarily know what is the most
logical thing to do on the HIGHER levels.

So, what is the solution then?
If you just return an error code, then the higher level
code has to examine it, and do different things, which simply
translates in additional and unnecessary complications in
your program logic, a "spaghetti effect".

You may have 5 levels deep stack, and on EACH level, you
have to test every single return code. Else your program
is incorrect.

So, you tend to forever deal with small and insignificant
things in the scheme of things, all of which, regardless
of how many levels deep on the stack it happened, could
be handled in bulk, with a single exception at the
appropriate higer level, that gives you sufficient
granularity to make a LOGICAL decision on what can be
done to recover the operation as such, and not some low
level funk, which is nothing more than a logic noise.

I am trying to use as little of logic as possible.

My slogan is: take it easy on your logic,
or you are bound to end up with grand headache,
no matter from what standpoint you look at it.

It will simply make your code more difficult to read.
How many decisions does you mind have to make, if it
forever worries about whether some return code was
handled correctly, of was handled in the right place
or what kinds of problems it might cause to the higher
level code.

Program logic = load on the mind.
Or in the method that called this method?
Or in the method that called the method that called the method where the
error happened?
etc

2) How do you handle errors in constructors?

You don't. Because you can not construct the object.
Your program is incorrect, and I doubt you can recover
from this kind of thing in principle in most cases.
3) Simple example : how would you create a method (or a function) that
reads a value (some random integer) from a file and returns that value?

--
Programmer's Goldmine collections:

http://preciseinfo.org

Tens of thousands of code examples and expert discussions on
C++, MFC, VC, ATL, STL, templates, Java, Python, Javascript,
organized by major topics of language, tools, methods, techniques.
 
J

James Kanze

Saying "Exceptions are for unrecoverable errors" seems to
imply that they are to be used only or mostly in such
situations.

Maybe, maybe not. It probably depends on what whoever is
saying it means by "unrecoverable". (But I've never heard
anyone say it, so I don't know the context.)
Whereas the exception machinery in C++ was developed primarily
to handle and RECOVER from more errors more elegantly than was
possible without exceptions, the statement is highly suspect.

It depends on the error. At the lowest level, where a simple
retry suffices, exceptions complicate error handling.
Those "unrecoverable errors" are probably the things that
assertion checking weeds out during development time rather
than being an application for exception machinery.

If that's what is meant by "unrecoverable", then exceptions are
certainly not for unrecoverable errors. In such cases, it's
important (in most applications---there are exceptions) to kill
the process as soon as possible, without any stack walkback.
"Unrecoverable error": throw up a dialog for the developer and
exit (or crash to keep the call stack in view in the
debugger).

Exactly. And that's not what exceptions do.
Exceptions, are more appropriately used where there is a
likelihood of recovering from the error condition rather than
being just for "unrecoverable errors".

Again, it depends on what you mean by "recovering". If you just
have to try again (e.g. user input error), then a simple while
loop is a lot simpler than an exception. Exceptions are useful
when you can't really do anything about the error locally.
Which often means that "recovery" is more or less impossible,
since once you've left "locally", you've lost all of the
necessary context to retry.

But maybe you mean something different by "recovering"?
Futher discussion of the application of exceptions is
appreciated. Keep in mind that while there are SOME general
vague "principles" of the application of exceptions, mostly
the scenarios need to be defined for fruitful discussion.
Please keep the examples simple but realistic and note the
assumptions you make.

Concrete example:

//! \pre
//! No current output set up...
void
SomeClass::setupOutput()
{
assert(! myOutput.is_open());
std::string filename = getFilename(); // Dialog with user...
myOutput.open(filename.c_str());
while (! myOutput.is_open()) {
reportErrorToUser();
filename = getFilename();
myOutput.open(filename.c_str());
}
}

Use of exceptions here would only make the code more
complicated. (Try writing it in Java sometime:). Where
failure to open a file is reported via an exception.)
 
J

James Kanze

More elegantly? Actually, for correct and secure C++ code,
all functions need to be written to be »exception safe«, but
only a minority of C++ programmers does so or even is aware
of it.

Just a nit, but the same holds true in any language which
supports exceptions. All code must be written with the fact
that some (or all, in the case of languages like Java) functions
can return via an exception, rather than the normal path.
These are distinct concepts for me: An unrecoverable error
can occur when a program needs 10 Bytes of allocated
storage, but this storage is not available. The program can
not generate more storage, so the error is not recoverable,
but it also can not be weeded out during developement time.

That's a particular definition of "unrecoverable". Is it the
one the original poster meant? I don't know.

Also, you know as well as I do that your example is simplified,
and only speaks of the general case. There are cases where you
attempt to allocate a large amount of memory, but can use a fall
back strategy in case of failure. I'd certainly be very upset
if, on trying to output data to a (non-essential) log, I got a
bad_alloc exception (especially if the logging was taking place
in a destructor, called because I'm unwinding the stack because
of another exception).
I prefer error results to exceptions. So all I would write
about exceptions would start with »If I was forced to use a
language that would force me to use exceptions ...«

I prefer to have a number of different tools in my toolbox, and
to use which ever one is most effective for the job at hand.
 
J

James Kanze

Stefan Ram wrote:
[snip]
More elegantly? Actually, for correct and secure C++ code,
all functions need to be written to be exception safe ,
but only a minority of C++ programmers does so or even is
aware of it.

Because your program doesn't work right otherwise.

Exceptions introduce an additional flow path into your code.
Fundamentally, all "exception safety" really means is ensuring
that the code is correct when this flow path is executed.
Practically, it's a bit more complicated than that, because the
number of additional flow paths soon makes the older,
traditional ways of reasonning about program correction
unmanageable; when C++ programmers speak of exception safety,
they are generally referring to the more recently developed
techniques to make this problem tractable. Effective use of
destructors, for example---I'm not sure you can write correct
code with exceptions unless the language has deterministic
destructors.
[snip]
I prefer error results to exceptions. So all I would write
about exceptions would start with If I was forced to use a
language that would force me to use exceptions ...
The applications of error results is as follows:
This should have probably been "switch" instead of "if" :
Back to return value vs exceptions.
1)
What happens if you can not handle the error in this method?

Then you might prefer an exception.
Or in the method that called this method?
Or in the method that called the method that called the method where the
error happened?
etc

The further up the stack you go, the more exceptions are called
for. It's important to realize, however, that the alternative
flow paths are still there, and that your code has to be correct
if they're taken.
2) How do you handle errors in constructors?

Or overloaded operators, or any other function which can't
return a value, or has its return type imposed.

The case of constructors is particular, however, in that an
exception coming from a constructor means that you don't have an
instance of the object at all. Which means that you don't have
to worry about an invalid instance floating around. This often
justifies exceptions even in cases where you wouldn't normally
use them.
3) Simple example : how would you create a method (or a
function) that reads a value (some random integer) from a file
and returns that value?

Fallible<int> readInt( std::istream& input );

Although in this case, it's even simpler, because istream
maintains an error state, which should be set if you can't read
the value.
 
J

James Kanze

Stefan Ram wrote:
[snip]
More elegantly? Actually, for correct and secure C++
code, all functions need to be written to be »exception
safe«, but only a minority of C++ programmers does so or
even is aware of it.
Why?
The above is false. Exception-safe code is needed to write
code that avoids resource leaks in the face of an exception.

It's need to write code that is correct in the face of an
exception. What "correct" means depends on the application
specifications. (On the other hand, what he wrote is false in
so far that if the function calls no other function, or only
calls functions guaranteed not to throw, it doesn't have to be
exception safe.)
For instance:
{
char *p = new char[256];
f();
}
If f throws an exception, this statement block is abandoned,
and the allocated memory is leaked.

Or not. If the application is using garbage collection, it's
not leaked. If the application immediately terminates (and is
in a hosted environment), it's not leaked.
Of course other kinds of resources can be leaked, like handles
to operating system resources such as open files.

And there can be other issues besides leaking. In the end,
you've got to ensure internal consistency for all possible
control flows. When some of the possible control flows are the
result of an exception, then this requirement is called
exception safety.
Leaking a resource is not automatically incorrect. Firstly, it
does not violate any C++ language rule. Allocating memory and
losing the pointer does not trigger undefined behavior.
Whether it is an issue or not depends on the precise situation
in which it occurs. Many C++ programs leak resources by
design simply because they lose references to objects when
terminating by returning via main.

Or by calling exit. (Calling exit does not unwind the stack,
which means that destructors of local variables are not called.)
This doesn't matter if the operating system cleans up the
resources after a program that terminated. Minor resource
leaks in short-lived programs are often not a problem.

More correctly, if the resource will be cleaned up by the
system, and you return to the system, it's not been leaked.
It's only a leak if you don't return to the system, or if it is
something which won't be cleaned up by the system. (Neither
Unix nor Windows clean up temporary files, for example.)

[...]
You set a ``successfully constructed'' flag in the object
which is tested after construction, through some public member
function.

And has to be asserted in every member function, so that you
don't accidentally use an invalid object. (There are cases
where this is valid, e.g. input or output. But they're not the
majority.)
There are a few ways. One is to store the integer via a
pointer or reference parameter and return the success/error
indication.

Yes. There are better solutions in C++ (at least in certain
cases). But people were writing robust, correct code even
before there were exceptions.
 
J

James Kanze

(e-mail address removed)-berlin.de (Stefan Ram) wrote:

[...]
Correct.
Almost everything you do will generate some kind of exception,
at least in modern languages, and it is good it does.

In order to write exception safe code, at least with value
semantics (and I suspect even without value semantics, but I've
not analysed the question in detail), it's been proven that you
need a certain number of primitives which are guaranteed not to
throw---one of the most classical C++ idioms, for example, only
works if you have a version of swap that doesn't throw.
 
T

tanix

Maybe, maybe not. It probably depends on what whoever is
saying it means by "unrecoverable". (But I've never heard
anyone say it, so I don't know the context.)

I like that one!
You do have a style and insight more than most people I saw.
That is why whenever I end up seing some articles while verifying
sites, and there is thread I am looking on, and there is article
from James Kanze, THAT is the article I am going to read first.
That is pretty much guaranteed.

To tell you the truth, I do not have even a concept of
"unrecoverable" error. Unrecoverable errors occur ONLY if my
box dies more or less.

In that case, exceptions or mental masturbation about them,
means as much as a dead mosquito fart. We are screwed.
But, as soon as I reboot, ALL I need to do "to recover",
is to push a SINGLE button. Since even the operation and ALL
its parameters will be automatically reloaded. Cause it is
all as persistant as it gets.

Not a big deal. I lost a couple of minutes of my time
and had a chance to go take a leak, instead of being glued
to the screen. What a pleasure!

:--}
It depends on the error. At the lowest level, where a simple
retry suffices, exceptions complicate error handling.

I do not agree. Sorry.
You DO have this tendency...
:--}

Ok, how do you retry a network connection?
You sit in some dumb loop and keep doing the same stoopid
thing, and you might have to do several things during
the connection process depending on what kind of protocols
the sever supports, and whether you need to do authentication
and what kinds of authentication methods sever supports,
or whether sever returns tens of codes, some of which may
be temporary off-line conditions to be retried.
Some may be permanent errors.
Some may be resource issues, and you name it.

So, to me, I just give a dead flying chicken what kind of
error server might have. There is only 2 level granularity
of exceptions.

I do not check ANY return codes more or less.

I can be thrown on two levels only, at most 3.
And ALL that funky logic does not have to be there.

Yes, I understand that your program does need logic.
Otherwise it is just a dumb state machine, even though
the very logic is already wired in into that state machine.
After all, they do execute conditional jumps depending
on which input bit is active.
If that's what is meant by "unrecoverable", then exceptions are
certainly not for unrecoverable errors. In such cases, it's
important (in most applications---there are exceptions) to kill
the process as soon as possible, without any stack walkback.


Exactly. And that's not what exceptions do.


Again, it depends on what you mean by "recovering". If you just
have to try again (e.g. user input error), then a simple while
loop is a lot simpler than an exception.

:--}

I like THAT one. Nice style!
Exceptions are useful
when you can't really do anything about the error locally.

Not necessarily.
Again the string to number conversion exceptions.
Can be handled as locally as it gets.
And plenty of other things.
I don't think there is such a rule for it.
Which often means that "recovery" is more or less impossible,
since once you've left "locally", you've lost all of the
necessary context to retry.

Not really.
You did loose the context withing the same stack frame.
Not a big deal.
Just make sure you handle that exception and clean up
some memory, even in Java you don't even have to worrry
even about doing that much.

Some local operation could be easily retried by the higher
levels in vast majority of situations, unless you read some
obviously wrong configuration parameter and it is not
going to work no matter how many times you retry it.
In that case, you throw on a higher level, after displaying
or logging the lower level, more precise and more detailed
result.

After that, you catch it on higher levels, and those levels
know much better what the whole operation is all about.
If they decide that, sorry, this can not be done even on
this level, they can rethrow even rougher generality
expception to the highest level loop.

At that point, your highest level logic knows what to do.
Either to wait for some time and try to retry, say in cases
where you lost a connection, which should be restored by
the O/S in a relatively short time.

Or, to simply abandon one of your major operations
and go on with the next item on the job list, if you have
anything like this, and THAT is where things become most
tricky.
But maybe you mean something different by "recovering"?


Concrete example:

//! \pre
//! No current output set up...
void
SomeClass::setupOutput()
{
assert(! myOutput.is_open());
Jesus!

std::string filename = getFilename(); // Dialog with user...
myOutput.open(filename.c_str());
while (! myOutput.is_open()) {
reportErrorToUser();
filename = getFilename();
myOutput.open(filename.c_str());
}
}

Use of exceptions here would only make the code more
complicated. (Try writing it in Java sometime:). Where
failure to open a file is reported via an exception.)

--
Programmer's Goldmine collections:

http://preciseinfo.org

Tens of thousands of code examples and expert discussions on
C++, MFC, VC, ATL, STL, templates, Java, Python, Javascript,
organized by major topics of language, tools, methods, techniques.
 
T

tanix

Stefan Ram wrote:
[snip]
More elegantly? Actually, for correct and secure C++ code,
all functions need to be written to be exception safe ,
but only a minority of C++ programmers does so or even is
aware of it.

Because your program doesn't work right otherwise.

Exceptions introduce an additional flow path into your code.
Fundamentally, all "exception safety" really means is ensuring
that the code is correct when this flow path is executed.
Practically, it's a bit more complicated than that, because the
number of additional flow paths soon makes the older,
traditional ways of reasonning about program correction
unmanageable; when C++ programmers speak of exception safety,
they are generally referring to the more recently developed
techniques to make this problem tractable. Effective use of
destructors, for example---I'm not sure you can write correct
code with exceptions unless the language has deterministic
destructors.

That is why I like to read your stuff.
You always seem to invent something kinky.
These are one of those rare times when I have to stop reading
all this jazz and start looking at it.

What a pleasure!

:--}

Most of other stuff I just scroll by.
[snip]
Futher discussion of the application of exceptions is
appreciated.
I prefer error results to exceptions. So all I would write
about exceptions would start with If I was forced to use a
language that would force me to use exceptions ...
The applications of error results is as follows:
This should have probably been "switch" instead of "if" :
Back to return value vs exceptions.
1)
What happens if you can not handle the error in this method?

Then you might prefer an exception.
Or in the method that called this method?
Or in the method that called the method that called the method where the
error happened?
etc

The further up the stack you go, the more exceptions are called
for. It's important to realize, however, that the alternative
flow paths are still there, and that your code has to be correct
if they're taken.
Deep.
2) How do you handle errors in constructors?

Or overloaded operators, or any other function which can't
return a value, or has its return type imposed.

The case of constructors is particular, however, in that an
exception coming from a constructor means that you don't have an
instance of the object at all. Which means that you don't have
to worry about an invalid instance floating around. This often
justifies exceptions even in cases where you wouldn't normally
use them.

Cool argument.
Fallible<int> readInt( std::istream& input );

Although in this case, it's even simpler, because istream
maintains an error state, which should be set if you can't read
the value.

--
Programmer's Goldmine collections:

http://preciseinfo.org

Tens of thousands of code examples and expert discussions on
C++, MFC, VC, ATL, STL, templates, Java, Python, Javascript,
organized by major topics of language, tools, methods, techniques.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Members online

Forum statistics

Threads
473,744
Messages
2,569,482
Members
44,901
Latest member
Noble71S45

Latest Threads

Top