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

sequence:

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

have:

#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

log2(283529).

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 (40°39.22'N, 111°50.29'W) +1 801 277 2603

email: forget about it

http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.