compile-time function - (nf)

chris at umcp-cs.UUCP chris at umcp-cs.UUCP
Wed Oct 19 18:13:44 AEST 1983

(I sent this as a reply, but I thought I'd better post it also, to
prevent people from believing something that isn't right.)

The example

	#define	fact(n)	(n == 1 ? 1 : n * fact (n-1))

doesn't put the compiler into a loop.  It puts the *preprocessor* into
a loop.  You've overlooked the fact that the preprocessor is a separate
entity, and does not know C.  The preprocessor does macro expansions
textually, not semantically.  The reason the LOG2 macro works is because
it's not textually recursive, and the compiler does constant folding.
If you were to define it as

	#define LOG2(n)	((n) == 0 ? 1 : 1 + LOG2(n/2))

you would again put the preprocesor into a loop.  (Eventually, at least
in the 4BSD cpp, you'll get a message about a macro stack overflow, or
something like that.)

Also, one thing that is almost a misfeature:  cpp looks only at lines
beginning with #, and at the same time folds multi-line #define's into
one line.  This makes things like

	#define fact(n) \
	#if (n) == 1 \
		1 \
	#else \
		((n) * fact(n-1)) \

useless.  (If that were not so, that macro would textually expand (e.g.)



	((6) *
	((6-1) *			/* Note to yale-com!lichter: */
	((6-1-1) *			/* I wrote these wrong in my reply. */
	((6-1-1-1) *			/* Sorry about that... */
	((6-1-1-1-1) *

which the compiler would fold into 720.  However, it might cause real
trouble if you gave it a variable instead of a constant...)
In-Real-Life: Chris Torek, Univ of MD Comp Sci
UUCP:	{seismo,allegra,brl-bmd}!umcp-cs!chris
CSNet:	chris at umcp-cs		ARPA:	chris.umcp-cs at CSNet-Relay

More information about the Comp.lang.c mailing list