J
James Kanze
James said:[...]"dragan" ha scritto nel
messaggionews:[email protected]...That's probably because there is no such chance.12. they not have "the written form"
"if(a/b > c) u=z;"
if "a/b" throw one exception
in the plain text above;
there is not a single char in
"if(a/b > c) u=z;"
that show this chanches
But seriously, this is the one real problem with exceptions. And
the possibility of exceptions does require some additional
thought. But the problem has been addressed, and we do know
what has to be done.That's the whole point of exceptions. They're for the sort of13. the "exception header" not "know" the point of code
where is the problem. Instead returning the error-result of the
function the program know where is the error
problems where it doesn't matter where the problem occured; the
handling is the same. If you run out of memory processing a
request, for example, it doesn't matter where you were in the
processing when you ran out; you just abort the request (but not
the process) with an error message, and continue.
You seem to be big on aborting.
Attention about word use. There's aborting (in the sense of
calling abort()), and aborting (in the more general sense, of
immediately terminating some action that you were in the process
of doing). In this case, I'm using the other sense: say you've
received a request on your LDAP server, and you run out of
memory trying to service it (because it requires interpreting
some obscenely complicated filter expression, for example).
When you detect the lack of memory, you're down in some really
deap parsing function, executing operator new. You (or rather
the system) raises an std::bad_alloc exception, which you catch
at the top level, and abort the request (not the program),
returning an error message of "insufficient resources", or the
like.
A very valid pattern is fixing the problem and resuming.
If that's a valid reaction to the error, aborting isn't the
answer. If the error was a coding error, you can't fix the
source, recompile the code, and resume, so you abort. If the
error was insufficient memory due to an overly complicated
request, you can't simplify the request and resume: you abort
the operation. (On receiving an "insufficient resources" error,
of course, the client may try a simpler request.)
Some version of Windows expands the stack that way: a
violation occurs when trying to push beyond the current stack
frame and the system catches the error, expands the stack by
4k and continues processing.
(Isn't that how most systems work? That's more or less the way
the old Berkley kernel worked on Sun 3's, and IIRC, PDP-11's
memory manager unit was designed expressedly to support
something like this, back in the days before virtual memory.)
I'm not too sure how that's relevant to user code, however. Are
you saying that if you get std::bad_alloc, you should try to get
more memory?
Frankly, out of memory is a special case, and most of the
programs I've worked on installed a new_handler to abort in such
cases. Not all, however, and particularly on transaction based
systems where transactions can require a lot of memory, it often
makes sense to just abort the transation. I can't think of much
else you could do: call some system routine to create more
virtual memory? That often requires priviledged access. And
if the insufficient memory was because you'd used up your
address space, rather than because the system didn't have any
more memory to give you, it won't help anyway. And you can do
it from the new_handler (which provides resumption semantics).