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