I want to make array whose length is (int)log(macro constant)
like
#define MACRO_NUM 100
int arr[(int)log(MACRO_NUM)];
But as you know, MSVC doesn't support variable-length array. So, declaring array, I can't use variable or function at index of array. It means every value determined in run-time couldn't become index of array. So I thought that preprocessor should do some kind of calculation before compilation if to do this possible.
So my question is
I know there's another ways like dynamic allocation with pointer etc, but, I just wander ,as a student, It is possible way to do this with array and macro constant when variable-length array is not supported.
No, the preprocessor doesn't do calculations, only substitutions and the other usual preprocessor stuff.
However, you can sometimes get a similar effect as follows. Pretty much anywhere in C that a compile-time constant is needed, you can use an arbitrary arithmetic expression whose operands are constants (which will be evaluated by the compiler, not the preprocessor). And a macro can be a convenient way to wrap such an expression, especially if it would otherwise be awkwardly long.
As a trivial example, you can do
#define SQUARE(x) ((x)*(x))
int foo[SQUARE(6)];
After preprocessing, this reads int foo[((6)*(6))];
and the compiler defines an array of length 36. The calculation was done by the compiler, not the preprocessor, but the effect is much the same.
Now log
isn't generally a function that the compiler can evaluate at compile time, but you can fake it:
#define MY_LOG(x) ((x) < 10 ? 0 : (x) < 100 ? 1 : (x) < 1000 ? 2 : .....)
with as many more ?:
as you need until you've exhausted the range of int
or long
or whatever. For log base ten it'll only be at most 10 or 20. And then you can do
#define MACRO_NUM 100
int arr[MY_LOG(MACRO_NUM)]
and get an array of length 2.
Just be careful that you don't ever use MY_LOG
with an argument that has side effects!