April 26, 2008
"Janice Caron" <caron800@googlemail.com> wrote in message news:mailman.465.1209106347.2351.digitalmars-d@puremagic.com...
> D2.013 just added the "nothrow" keyword, so that one can write, e.g.
>
Disclaimer: I know nothing about the internals of compilers, so take it with
a grain of salt:
It seems to me that the compiler could figure out whether or not a function
throws exceptions and act accordingly; I really don't see why it needs to be
told. That means the only real use of nothrow that I could see would be to
say that you don't want this function ever throwing an exception in any
current or future incarnation.
>    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?


April 26, 2008
On 26/04/2008, Ameer Armaly <ameer.armaly@furman.edu> wrote:
>  It seems to me that the compiler could figure out whether or not a function
>  throws exceptions and act accordingly;

Without the nothrow keyword, the only way it could do that is by checking not only the function itself, but the function bodies of all functions called by the function, and so, recursively, forever.


> I really don't see why it needs to be
> told.

With nothrow, it doesn't have to recurse.
April 27, 2008
Janice Caron wrote:
> On 26/04/2008, Ameer Armaly <ameer.armaly@furman.edu> wrote:
>>  It seems to me that the compiler could figure out whether or not a function
>>  throws exceptions and act accordingly;
> 
> Without the nothrow keyword, the only way it could do that is by
> checking not only the function itself, but the function bodies of all
> functions called by the function, and so, recursively, forever.
> 
> 
>> I really don't see why it needs to be
>> told.
> 
> With nothrow, it doesn't have to recurse.

Yeh, it's the same problem with deducing things like pure and const (which is the conclusion I came to following our previous discussion on the topic... though I just let the thread fizzle rather than stating this conclusion.).

If you want to have the benefits of separate compilation then you have to tell the compiler what to expect of functions without it having to have the bodies of those functions present.

--bb
April 28, 2008
"Janice Caron" wrote
> On 26/04/2008, Ameer Armaly wrote:
>>  It seems to me that the compiler could figure out whether or not a
>> function
>>  throws exceptions and act accordingly;
>
> Without the nothrow keyword, the only way it could do that is by checking not only the function itself, but the function bodies of all functions called by the function, and so, recursively, forever.

Enter your algorithmic friend, memoization :)  The compiler could store attributes with the functions as they are compiled, marking ones which don't throw exceptions and ones which are pure, etc. in the object files.

The only issue then is if you are a developer and you desire a function to be a nothrow, it must be marked by the developer.  Otherwise it's like inlining.  You never know which functions will be marked nothrow/pure and which ones will not.  It also becomes a question of maintainability, if one makes a change in a nothrow function that throws an exception, this is no good for dynamic libraries, who may depend on it keeping the nothrow status.

-Steve


1 2 3
Next ›   Last »