Re: Exception handling Organization: unknown
On 2009-09-30, Goran <goran.pusic@gmail.com> wrote:
Apropos that, where/how is that object allocated?
I have to ask: do you think that matters? I can easily say: no, it
does not. But let's explore that, fire away.
And most importantly, WHEN is it allocated? It matters if the implementation
of exceptions has to be robust -- what happens if there is not enough memory
to allocate the exception object? You can't throw bad_alloc, because that's
an object as well.
Compare to error-return:
if(!(f = fopen(...))) crap!
if (!read(f...)) crap!
if (!read(f...))crap!
It will most likely be if(read(...) != expected_amount) // crap!
And note that it is valid (and often practical) to specify a larger
buffer size to read than the size of data you expect.
In your opinion, should a partial read throw an exception or not?
Exceptions are so intrusive mechanism that no code should use it for reporting
anything but "something has become FUBAR." File not found, failing to parse an
integer, key not found in a dictionary are not FUBARs. Accessing a
non-existant element in a vector is (undefined behavior), as would be e.g.,
deleting an already deleted object (a situation sadly often not detected), or
corrupting a state of some object through a rogue pointer (and the object's
methods detect it).
Whoa, whoa... No, no, no, the last three are a cold crash. Exceptions
do not matter __in the slightest__. Just stop that.
No, the last three are valid examples of what can go wrong. vector::at throws
an exception for an out-of-range index. An object's state can be corrputed
(i.e., the object's invariants broken) by bugs other than invalid memory
accesses. Double delete is indeed a "cold crash", but why should it be? By
sacrifising some performance, a smart memory allocator could detect it.
When code loses control of it's memory, it's probably best that it
dies as quickly as possible. All of these problems are caused by a
Indeed, but double delete will most likely not crash the program immediatelly.
You are horribly, __horribly__ mistaken here!
My only mistake was using rogue pointers as one possible cause of FUBARs. As I
explained above, these FUBARs are still valid scenarios even when all
memory-operations are clean. Attempting to access a vector beyond its last
valid index is a clear FUBAR and at() should (and does!) therefore throw.
To me, OOM is a clear-cut use case for exceptions. Having to check
every single allocation? No thanks, I've got better things to do in
life!
Which returns us to the first question: how/where/when is the bad_alloc
object allocated?
By the way, do you wrap all your non-trivial destructors in a try { }
catch(...) { } clause?
Ah... That's rule 0 of exceptions you're ignoring here: destructors
must not throw. That's not specific to C++, and there's more general
rule behind that. The rule is: cleanup operations always "succeed" (or
else, code is a mess). We can discuss that, too.
I asked that question exactly because I know about that rule. Can you *prove*
by static inspection of your code (i.e., without testing it) that none of your
destructors throws?
Fair enough, however... I said (but now, with precision) "__First__,
use stat or PathFileExists" ;-). In a way, what you propose is a silly
design: you want to know if a file exists; to do that, you __open__
it. WTF, isn't there a better way!?
Not within the boundaries of standard C and C++, as far as I know. And on
some platforms, there might not be a better way.
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]