F
Francois Grieu
I'm trying to figure out the exact limitations that (possibly:
various versions of ISO/IEC 9899) C puts to expressions defining
the size of a plain array at compile time, and how to workaround
that.
An application would be, given EXPECTED, to define at compile
time an array with EXPECTED + 12*sqrt(EXPECTED) elements, or
some even more complex formula, as required by
http://stats.stackexchange.com/q/35658/8469
A tentative (not tested)
#define EXPECTED 15000
/* define an array of EXPECTED + 12*sqrt(EXPECTED)
pointers to struct foo (or slightly more) */
struct foo * bar[
#if (EXPECTED)<900
#error "unsupported EXPECTED value"
-1
#elif (EXPECTED)<3600
(EXPECTED)+360+((EXPECTED)-896)/5
#elif (EXPECTED)<14400
(EXPECTED)+720+((EXPECTED)-3591)/10
#else
(EXPECTED)+1440ul+((EXPECTED)-14381ul)/20
#endif
];
I think the above works for any EXPECTED>=900 up to
some large value like ULONG_MAX-ULONG_MAX/19 and then some,
and errs on the safe side, with at worse 5% wasted memory;
but this is
- unclear at best;
- painful to extend to lower bounds or less wasted memory;
- hard to generalize to more complex formula involving
for example log or exp.
Can I
- use floating point at all ?
- if yes: use sqrt, log, exp ?
- or at least, use intermediate values (other than
macro identifiers) to clarify things and remain below
the "4095 characters in a logical source line" limit?
I can think of enum as intermediates, and have done that
when computing a CRC at compile time, but they have rather
silly range limitations.
François Grieu
various versions of ISO/IEC 9899) C puts to expressions defining
the size of a plain array at compile time, and how to workaround
that.
An application would be, given EXPECTED, to define at compile
time an array with EXPECTED + 12*sqrt(EXPECTED) elements, or
some even more complex formula, as required by
http://stats.stackexchange.com/q/35658/8469
A tentative (not tested)
#define EXPECTED 15000
/* define an array of EXPECTED + 12*sqrt(EXPECTED)
pointers to struct foo (or slightly more) */
struct foo * bar[
#if (EXPECTED)<900
#error "unsupported EXPECTED value"
-1
#elif (EXPECTED)<3600
(EXPECTED)+360+((EXPECTED)-896)/5
#elif (EXPECTED)<14400
(EXPECTED)+720+((EXPECTED)-3591)/10
#else
(EXPECTED)+1440ul+((EXPECTED)-14381ul)/20
#endif
];
I think the above works for any EXPECTED>=900 up to
some large value like ULONG_MAX-ULONG_MAX/19 and then some,
and errs on the safe side, with at worse 5% wasted memory;
but this is
- unclear at best;
- painful to extend to lower bounds or less wasted memory;
- hard to generalize to more complex formula involving
for example log or exp.
Can I
- use floating point at all ?
- if yes: use sqrt, log, exp ?
- or at least, use intermediate values (other than
macro identifiers) to clarify things and remain below
the "4095 characters in a logical source line" limit?
I can think of enum as intermediates, and have done that
when computing a CRC at compile time, but they have rather
silly range limitations.
François Grieu