compile-time function - (nf)

Jerry Leichter leichter at yale-com.UUCP
Sun Oct 16 00:11:27 AEST 1983


You can get your particular example to work by doing:

#define LOG2(n) ((...(n == 2) ? 1 ) : (n == 4) ? 2 : ...

(You can probably do without all the parens, but I can never remember for
sure how precedence and associativity works for ?: so I play it safe...)

The above will give you the code you want as a side-effect of constant folding,
which is present in every C compiler worth looking at.

It's an interesting fact that many compilers do constant folding over expres-
sions, but hardly any - in fact, I don't know of any at all - do it across
statements - although taking constants out of loops is, in a sense, doing
exactly that.  I don't think any C compiler will "fold"

	if (2=1)
		a = 0
	else if (2 == 2)
		a = 1
		etc.

This is unlikely to come up, except in code generated by some other program
(or a macro - but C macros aren't really very handy for constructing more
than single statements anyway) - but this isn't common, so the compilers aren't
designed to deal with it.

So:  In answer to your general question:  If you can express your compile-
time function as a single expression, constant-folding should get you the
effect you desire.  The presense of the ?: operator means you can put in
conditionals.  You can also put in calls to other macros.  Unfortunately,
you CANNOT use recursion:

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

will put every C compiler I've ever seen in a loop:  Unfortunately, the
compile-time evaluators do NOT respect the "non-monotonicity" (to use the
term from formal semantics) of :?, &&, and ||.  They always evaluate ALL
arguments, and then discard the one they don't need.  I.e.

	a = (X == 0) : 0 ? (1 / X)

(where X is a pre-processor constant) SHOULD work; it would work if X were a
variable; but it will cause most C compilers to die a horrible death when
X happens to be 0.

If :? was handled correctly, #define could be used recursively and the resulting
compile-time language would be universal.  (At least in principle.  Most C
compilers also have some hard limits on expression complexity, and will blow
up if you really try this for more than "toy" cases.)
							-- Jerry
					decvax!yale-comix!leichter leichter at yale



More information about the Comp.lang.c mailing list