I have a macro to repeat macros that I use to fill arrays with default values in compile time:
const int array [512] =
{
MACRO_REPEAT(512, -2) // this repeats -2, 512 times
[4] = 10,
[5] = 2,
...
}
The macro repeat will expand to MACRO_REPEAT_512, but now I wanted to use other macros as the array size, like:
#define ARRAY_LENGTH 512
const int array [ARRAY_LENGTH ] =
{
MACRO_REPEAT(ARRAY_LENGTH , -2) // this repeats -2, 512 times
[4] = 10,
[5] = 2,
...
}
But this expands to MACRO_REPEAT_ARRAY_LENGTH, doesn't expand ARRAY_LENGTH
value before concatenating it. Other example would be for multi-dimensional arrays, which involves more levels of expansion:
#define X 512
#define Y 512
const int array [X][Y] =
{
MACRO_REPEAT(X*Y , -2) // this repeats -2, 512 times
[4] = 10,
[5] = 2,
...
}
This will expand to MARO_REPEAT_X*Y. So, is there a way to expand those values to the final numerical value before concatenating it to other macros?
You can solve the MACRO_REPEAT(ARRAY_LENGTH , -2)
case by changing the definition of MACRO_REPEAT
to use 2 stage expansion, ie do not use token pasting in MACRO_REPEAT
itself, invoke another macro that does.
Not that this will only work as expected if ARRAY_LENGTH
is defined as a single number token and if there is a macro definition for this specific size.
You cannot handle the more general MACRO_REPEAT(X*Y , -2)
case with the standard C preprocessor.
You can use the gcc extension to initialize simple arrays:
#define MACRO_REPEAT(n, e) [ 0 ... (n)-1 ] = e,
But this method cannot be used to handle multidimensional arrays such as MACRO_REPEAT(X*Y , -2)
.
You could try this:
#define MACRO_REPEAT(n, e) [ 0 ... (n)-1 ] = e,
#define X 512
#define Y 512
const int array[X][Y] = { MACRO_REPEAT(X, { MACRO_REPEAT(Y, -2) }) };
But the use of the C preprocessor just obfuscates the intent. If you decide to rely on gcc extensions, just use them directly.