|
Boost : |
From: Stewart, Robert (stewart_at_[hidden])
Date: 2002-03-20 11:37:00
From: Brey, Edward D [mailto:EdwardDBrey_at_[hidden]]
>
> The problems with requiring programmer to inspect the return value are
> well-known and were a great motivation for the invention of
> exceptions. I
Certainly.
> think regressing to a check-the-return-code pattern would be
> a bad idea
> unless we knew that it would be very rare when anyone cared.
There are two reasons to use a return code approach: the error is benign and
needing to know about it is rare. I think both apply to remove() failing
because the file didn't exist. There are few cases in which one cares why a
file doesn't exist when remove() returns. Ignoring the error code doesn't
make one's code misbehave thereafter; the effect is the same whether
remove() removed the file or it didn't exist when remove() tried to remove
it.
> However, I
> think that in many applications, overall system robustness
> and diagnostics
> would benefit from asserting that the remove was successful,
> and it would be
> good to make this as easy for the programmer as possible,
> lest we be tempted
> to be lazy and just skip it (ignore the return value).
Why is it so important to know that the file didn't exist when remove()
tried to remove it! I certainly agree that we shouldn't rely on return
values to indicate other sorts of errors, but this one seems a no-brainer.
> What makes this dilemma trickier than most is that often,
> even though we
> want to know about the problem, we don't really want to interrupt our
> control flow. That is, we want to limp on as best as we can.
>
> To solve this problem, I propose that the file IO functions
> be nested in a
> error notification context. Basically, it would be like this:
>
> class file_io_context {
> public: // Setup
> void set_listener( void (* listener)(error_type) );
>
> public: // File manipulation
> void remove(string filename);
> };
This is fine, but I guess I'd name it "set_error_handler" and it should
return the previous handler. The unfortunate thing is that file_io_context
would need to replicate the entire filesystem library interface or vice
versa (assuming the free functions would install a handler that throws
exceptions after restoring the original handler).
> Now if remove fails, it calls the registered listener.
> Likewise there could
> be states variables set as to which errors are reported
> and/or throw, if
> such flexibility is necessary (I'm not sure).
That would be up to the handler function.
> > > In my Python script for performing the formal builds of our
> > > software, I am
> > > quite happy when the script throws an exception when I tell
> > > it to remove a
> > > file that I expect should be there but isn't. It's basically
> > > like getting a
> > > free assertion in the code.
> >
> > I'd hate having to write, or even execute code that ignores
> > an exception
> > raised by such a common and (nearly always) benign condition.
> > Throwing an exception is too heavyweight for something like this.
>
> This is a good demonstration that there are at least two
> different use cases
> for the file IO library. Setting up try blocks for each
> remove is too much
> coding. Likewise, checking the return value from each remove
> is too much
But you don't need to check it in most cases.
> coding. Having a remove and a remove_if_exists helps, but it
> doesn't handle
> the case where you want to be notified of the problem but not have it
> interrupt the program flow. For that you need an error notification
> context.
Agreed.
Rob
Susquehanna International Group, LLP
http://www.sig.com
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk