Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!mnetor!seismo!think!ima!haddock!karl From: karl@haddock Newsgroups: net.lang.c Subject: Re: Orphaned Response Message-ID: <86900032@haddock> Date: Wed, 3-Sep-86 14:13:00 EDT Article-I.D.: haddock.86900032 Posted: Wed Sep 3 14:13:00 1986 Date-Received: Wed, 3-Sep-86 21:51:31 EDT References: <1074@dataio.UUCP> Lines: 55 Nf-ID: #R:dataio.UUCP:1074:haddock:86900032:000:2453 Nf-From: haddock!karl Sep 3 14:13:00 1986 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. dataio!bright writes: >In article <86900019@haddock> karl@haddock writes: >>[2] It won't be usable much. This is a valid point. There were a *lot* of >>nonvalued int functions before void was invented; there are only a handful >>of standard functions that are dead-ends. > >Functions that never return are used a LOT in code that is loaded >with self-debugging assertion macros: > #define assert(e) ((e) || printmsgandexit("e",__LINE__,__FILE__)) But there are typically a very small number of such functions (usually one) per application. (Btw, I wouldn't want to assume that a dead function can be the right argument of "||".) >A good optimizer can make some important optimizations [with register usage, >information about global and indirect references] if it knows that a >function will never return. Good point. I hadn't thought of that type of optimization. Another "advantage" of an explicit declaration for dead functions is that, logically, one should be able to cast from "dead" into any other type -- a feature not available with "void". Since the code that would implement the cast is never reached, it need not do anything. This would allow extern double atod(); extern dead abort(); x = isfloatstr(s) ? atod(s) : abort(); which is a pretty bad example, so let me try again. "pointer to dead function" (I can't really call it "pointer to function returning dead", can I?) could be cast into "pointer to function returning T" for any type T. This would allow extern T f0(), f1(), f2(), f4(); extern dead abort(); T (*)() tab[] = { f0, f1, f2, abort, f4 }; Note that this can ALREADY BE DONE using an implicitly dead function. The functions in libc are declared "void" (that being the closest match), but it is perfectly legal to write double bomb(char *s) { write(2, s, strlen(s)); exit(1); } An explicit "dead" declaration, with permission to cast to other types, would seem to be more sensible. (Though I think I'd want to require the cast to be explicit.) Karl W. Z. Heuer (ima!haddock!karl; karl@haddock.isc.com), The Walking Lint (The opinions expressed above are not necessarily those of the author.)