What is nothrow for?
Janice Caron
caron800 at googlemail.com
Thu Apr 24 23:52:14 PDT 2008
D2.013 just added the "nothrow" keyword, so that one can write, e.g.
inf f() nothrow
{
return 42;
}
to indicate that f does not throw an exception. My question is, what's
the point?
The documentation notes that the semantics are not implemented, but I
have to ask, why is this desirable in general?
Like any annotation, "nothrow" indicates a /contract/. Like any
annation, there are two rules
(1) if a function is annotated with the nothrowkeyword, then the
compiler will emit a compile error within the function body, if the
function body of f throws an exception.
(2) if the caller of a function requires that the the called function
not throw any exceptions, then the compiler will emit a compile error
at the caller site if the callee is not annotated with the nothrow
keyword.
Rule one helps the human. Rule two helps the compiler - but positively
/hinders/ the human. The problem is one of logical fallacy - given the
proposition "all dogs have four legs", one may /not/ assume that if it
has four legs, it must be a dog. Likewise, given the proposition "any
function decorated with the nothrow keyword will not throw an
exception", one may /not/ assume that if it doesn't throw an
exception, then it will be decorated with the nothrow keyword. Here's
a simple counterexample:
int f() { return 42; }
int g() nothrow { return f(); }
Once the semantics of nothrow are implemented, the above code will not
compile. This is because, /even though/ f doesn't throw any
exceptions, the compiler isn't able to prove that (or at least, can't
be bothered to prove that) at the time g is compiled.
Like all annotations, "nothrow" therefore /propogates/ throughout
code. In order to get the above to compile, the user must now decorate
f.
This is all very well, unless f is in a library, and the user is
unable to modify f. In that case, presumably the user must do
something like:
int g() nothrow { return cast(nothrow) f(); }
or perhaps
int g() nothrow
{
try { return f(); }
catch(Exception e) { return 0; }
}
Sure - we could decorate /every/ function which does not throw an
exception with "nothrow", but are we really going to do that?
So I guess my question is, in what circumstance would "nothrow" be
helpful? And is it helpful /enough/ to warrant "polluting" all library
code with "nothrow" annotations?
More information about the Digitalmars-d
mailing list