Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Preprocessor log()?

Thread Tools

Preprocessor log()?

Richard Cavell
Posts: n/a

I want to do something like this:

const int a = "283529";
const int b = log to base 2 of a;

and have it *at compile time*.
Reply With Quote
Chris Torek
Posts: n/a
In article <cvrcg3$o4b$(E-Mail Removed)>
Richard Cavell <(E-Mail Removed)> wrote:
>I want to do something like this:
>const int a = "283529";
>const int b = log to base 2 of a;
>and have it *at compile time*.

You cannot even do this:

% cat foo.c
const int a = "283529";
% cc -ansi -pedantic -c foo.c
foo.c:1: warning: initialization makes integer from pointer without a cast

Presumably you did not really mean to include the quotes.

If we fix that, so that "a" is a read-only variable initialized to
283529, we still have several problems, the first being that "a"
is a variable. You cannot initialize a second static-storage-duration
variable based on another variable; you can only use constants to
initialize static-duration variables. Remember that, in C, const
means "do not define a constant". (There are other languages in
which const *does* mean "constant"; but if you mean to use one of
those languages, you are in the wrong newsgroup.)

We can repair this by initializing both variables (whether read-only
or not) from a true constant, using either "#define" or "enum". Note,
however, that 283529 is a large enough value that it might exceed
the range for "int", so we really should use "long", and a #define
-- enumeration constants have type int, and if INT_MAX is 32767, the

enum { A = 283529 };

should draw a diagnostic. (If INT_MAX is 2147483647, as it is on so
many implementations today, no diagnostic is required.) So now we

#define A 283529
const long a = A; /* or int, if you are sure INT_MAX >= 283529 */
const int b = SOME_MACRO(A);

and we need to find a way to define SOME_MACRO so as to obtain

Now we have one final problem: log2(283529) is approximately
18.113136779327283. What integer value do you want to represent
this? Both 18 and 19 are "reasonable" but at most one of them
is correct (although perhaps neither is correct).

Depending on your answer to this last problem, there is an obvious
way to define SOME_MACRO:

#define SOME_MACRO(x) \
((x) > 65536 ? [one set of options] : [other set of options])

where the expansion of one of the sets-of-options is:

(x) > 256 ? [one set of options] : [another set of options]

and these options again expand to something like:

(x) > 16 ? [one set of options] : [another set of options]

and so on, ending with:

(x) > 1 ? 1 : 0

(with an optional test for x < 1 as well, although what value to
use here is again a puzzle).

(This version, with the tests for ">", is designed for rounding
up, so that b will be set to 19, based on A > 262144; if A is
between 131073 and 262144 inclusive, the result would be 18.)
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (4039.22'N, 11150.29'W) +1 801 277 2603
email: forget about it
Reading email is like searching for food in the garbage, thanks to spammers.
Reply With Quote
Kevin Bracey
Posts: n/a
In message <cvrcg3$o4b$(E-Mail Removed)>
Richard Cavell <(E-Mail Removed)> wrote:

> Hi,
> I want to do something like this:
> const int a = "283529";
> const int b = log to base 2 of a;
> and have it *at compile time*.

Chris Torek's answered this for your specific code. But here's my take.

The only straightforward way to do this sort of thing in the _general_ case
is to write a small program which is run at build time to generate the
required constants. For example:

#include <stdio.h>

int main(int argc, char **argv)
printf("const int a = %d\n", atoi(argv[1])));
printf("const int b = %d\n", (int) log2(atoi(argv[1]))); /* rounding? */
return 0;

then in your makefile

cc mkconstant
../mkconstant 283529 > constants.c

and #include "constants.c" where required.

Obviously this is extensible to large data tables etc. (Although in that case
computing at run-time may be better if memory is more important than start-up

The only thing to be wary of (particularly for math.h functions) is that you
may get different answers at build-time and run-time if your host and target
platforms are different.

Kevin Bracey, Principal Software Engineer
Tematic Ltd Tel: +44 (0) 1223 503464
182-190 Newmarket Road Fax: +44 (0) 1728 727430
Cambridge, CB5 8HE, United Kingdom WWW:
Reply With Quote

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off

Similar Threads
Thread Thread Starter Forum Replies Last Post
Compiler error occurred when try to use a flexible template expression in preprocessor definesCompiler error occurred when try to use a flexible template expression in preprocessor defines snnn C++ 6 03-14-2005 04:09 PM
C# Preprocessor =?Utf-8?B?SSBhbSBTYW0=?= ASP .Net 2 03-13-2005 02:47 PM
preprocessor, token concatenation, no valid preprocessor token Cronus C++ 1 07-14-2004 11:10 PM
VHDL Preprocessor The Weiss Family VHDL 2 07-14-2004 05:51 AM
Preprocessor conditional compilation variable not being saved Chris P ASP .Net 0 10-28-2003 08:48 PM