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