Orphaned Response

Walter Bright bright at dataio.UUCP
Sat Aug 23 02:31:39 AEST 1986


In article <86900019 at haddock> karl at haddock writes:
>ccvaxa!aglew (Andy Glew) writes:
>>[haddock!karl (Karl Heuer) writes:]
>>>I was trying to declare "typedef void dead;" so that I could distinguish
>>>between functions that return nothing (void perror(char *), setbuf(FILE *,
>>>char *), nullf(void)) from those that don't return (dead exit(int),
>>>abort(void), longjmp(jmp_buf, int)).
>>
>>Good point, though - an optimizing compiler could take advantage of
>>knowledge that a function doesn't return to do better register allocation,
>>etc.
>
> The only
>reasons for not adding [dead functions], as far as I can see, are as follows:
>
>[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__))

>As for optimization, the calling
>function can take advantage of the knowledge by omitting extra branches (e.g.
>in "if (err) exit(1); else ...") or returns ("exit(0)" at the bottom of
>main()).  This improves the space (but not time) efficiency, but not by much.
>
>I presume your comment about register allocation referred to the dead-end
>itself, in that the caller's registers need not be saved.  I don't think you
>can assume this: the function "dead f() { for (;;) pause(); }" could be
>interrupted by a signal, whose handler could longjmp() to f's caller, whose
>registers must be recoverable.  For similar reasons, it probably isn't okay
>to optimize the function call into a jump, unless you're careful with the
>stack.

	A good optimizer can make some important optimizations if it
	knows that a function will never return:

	1) Register contents destroyed by the function call do not affect
	the caller. This has important ramifications when doing register
	allocation by coloring.

	2) Functions are presumed to modify all globals and all indirect
	references. Thus, if the function does not return, the optimizer
	can find more common subexpressions, copy propagations, etc.



More information about the Comp.lang.c mailing list