Eof - to return or to throw?
Andrei Alexandrescu (See Website For Email)
SeeWebsiteForEmail at erdani.org
Mon Feb 12 16:54:46 PST 2007
Dawid Ciężarkiewicz wrote:
> I've just asked Kris why mango is not throwing Eof in it's I/O operations
> instead of returning it.
>
> After short discusion he told me to ask about your opinons on NG (probably
> to stop me from distrupting him ;) ).
>
> So here am I.
>
> Two versions of same functionality.
>
> SomeIOClass {
> /* throws Eof, 0 == nothing available */
> return uint readWithThrowingEof(void[] buf);
>
> /* -1 == eof, 0 == nothing available */
> return int readWithReturningEof(void[] buf);
> }
>
>
> Which is better?
>
> I've always thought about returning Eof as an workaround when you can't
> throw it or it is too costly. Like in C.
>
> I mean:
>
> try {
> auto amount = io.readWithThrowingEof(buf);
> useData(buf, amount);
> } catch (Eof e) {
> /* do smth */
> }
>
> Isn't any worse than:
>
> auto amount = io.readWithReturningEof(buf);
> if (ammount >= 0) {
> useData(buf, amount);
> } else if (ammount == -1) {
> /* do smth */
> }
>
> 6 lines vs. 6 lines
>
> But when dealing with multiple reads, try block is _much_ better. In ideal
> situation you can only have one try {} catch {} and just read, use, read,
> use etc. I can come with many examples where catching/throwing Eof is more
> flexible both for implementator and library user and the difference is BIG.
> Especialy in D with great exception support.
>
> But are there cases where readWithReturningEof is better? Can someone give
> me a snippet that we could discuse on? I really have no idea where
> returning magical value Eof could be more handy than throwing it.
It's very simple, really: from error codes to throwing is a shorter and
easier path than vice versa.
All you have to do is:
try {
auto amount = ThrowEof(io.readWithReturningEof(buf));
useData(buf, amount);
} catch (Eof e) {
/* do smth */
}
ThrowEof is an identity function (see? the identity function I discussed
a while ago wasn't that silly...) that returns whatever goes through it,
not before checking for -1 and throwing if that's the case.
One could also write a converse function ThrowProtect that does the
opposite, but it's less clear and less efficient.
Andrei
More information about the Digitalmars-d
mailing list