[net.lang.c] Functions that never return

atbowler@watmath.UUCP (Alan T. Bowler [SDG]) (09/20/86)

In article <86900032@haddock> you write:
>
>Note: In my earlier posting I came to the tentative conclusion that the "dead
>function" concept (a function which never returns, e.g. exit) would probably
>not be sufficiently useful to be worth adding a new builtin type.  I haven't
>changed my mind; I just want to point out some possibilities.
>
There are library functions "exit", "longjmp", "abort" that never
return.  Most implementations will have quite a few more,
and using these users will normally construct a number of others.
A larger program is very likely to have several error handlers
that print a message, do some cleanup and longjmp back to
a good restart point.
   On the observation that this is a "goto" type of action
why not just recycle the "goto" keyword and allow it in function
type declarations. e.g.
    extern goto exit(int);

1) It does not require a new keyword.
2) It is compatible with the existing language
3) It is reasonably obvious what it means
4) The compiler gets the optimizing hint it needs
   without requiring a flow analysis that goes outside the
   function boundaries (i.e. you don't have to sacrifice
   separate compilation to have an optimising compiler take
   advantage of it).
5) On a similar note it gets rid of the damned 
   /*NOTREACHED*/
   by associating the property of not returning with
   the function instead of with every call to the function.

karl@haddock (09/22/86)

watmath!atbowler writes:
>In article <86900032@haddock> [haddock!karl] writes:
>>In my earlier posting I came to the tentative conclusion that the "dead
>>function" concept (a function which never returns, e.g. exit) would probably
>>not be sufficiently useful to be worth adding a new builtin type.
>
>There are library functions "exit", "longjmp", "abort" that never return...
>On the observation that this is a "goto" type of action why not just recycle
>the "goto" keyword and allow it in function type declarations. e.g.
>    extern goto exit(int);
>
>1) It does not require a new keyword.

If I had to choose between adding a new keyword vs. using the same word for
flow-control and type-specification, I'd choose the former.  I'm still
urinated off about the double meanings of "static" and "break".

>2) It is compatible with the existing language

Adding a new keyword will not obsolete any programs except those that use it
as an identifier.  Such programs are easy to upgrade ("#define dead id_dead"
is almost sufficient, if you're lazy).  Conversely, programs written for the
new language can be downgraded for old compilers with "#define dead void" --
no such simple fix is available if "goto" acquires new semantics.

>3) It is reasonably obvious what it means

I'll grant that.

>4) The compiler gets the optimizing hint it needs ...

True with either "goto" or "dead", of course.  This, and Say-What-You-Mean,
are (I think) the only arguments in favor of adding the feature at all.

>5) On a similar note it gets rid of the damned /*NOTREACHED*/

As I pointed out before, this can be handled by making lint smarter:
"void exit(int) { for (;;); }" should suffice, and doesn't even require a
new lint-comment.

Karl W. Z. Heuer (ima!haddock!karl or karl@haddock.isc.com), The Walking Lint

rbutterworth@watmath.UUCP (Ray Butterworth) (09/24/86)

> >5) On a similar note it gets rid of the damned /*NOTREACHED*/
> As I pointed out before, this can be handled by making lint smarter:
> "void exit(int) { for (;;); }" should suffice, and doesn't even require a
> new lint-comment.

Exactly where would you put this "void exit(int) {for (;;);}" ?
I imagine you mean putting it in the lint library, but if that is
the case, lint won't see it until the second pass.  It is the first
pass that needs to know that exit() doesn't return, just as it is
there that it needs to know what type it returns, and so this
information must be provided in the header file (or wherever) that
declares exit() as being of type (void).

At the moment, the header file contains at most "extern void exit(int);",
and there is nothing in that statement that indicates that the function
does not return.  To convey this information you must change the language
in some way, either by creating a new type (e.g. (goto)) or by creating
a new lint directive (e.g. /*GOTO*/).  Adding the lint directive is
easier to do; while adding the new type enables the compiler to generate
more efficient code.  The two different compilers we use here use those
two different approaches, and they are very useful for finding sections
of code that are never reached.

chris@umcp-cs.UUCP (Chris Torek) (09/27/86)

In article <3347@watmath.UUCP> rbutterworth@watmath.UUCP (Ray
Butterworth) writes:
>Exactly where would you put this "void exit(int) {for (;;);}" ?
>I imagine you mean putting it in the lint library, but if that is
>the case, lint won't see it until the second pass.  It is the first
>pass that needs to know that exit() doesn't return ....

What first pass?  What second pass?  (I know: the ones in your
implementation.  Yes, they are there in mine as well.  What does
that matter?)

Perhaps it is just a Small Matter of Programming, but at least in
an initial design phase---which is all this is likely ever to be---
one should not worry about implementation details.

[For those who have not heard the phrase, SMOP, a Small Matter of
Programming, is an ironic term attached to programming tasks that
are by no means trivial.]
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 1516)
UUCP:	seismo!umcp-cs!chris
CSNet:	chris@umcp-cs		ARPA:	chris@mimsy.umd.edu