C целью расширения макроса
у меня есть макрос для повторения макросов, которые я использую для заполнения массивов значениями по умолчанию во время компиляции:
const int array [512] =
{
MACRO_REPEAT(512, -2) // this repeats -2, 512 times
[4] = 10,
[5] = 2,
...
}
повторение макроса расширится до MACRO_REPEAT_512, но теперь я хотел использовать другие макросы в качестве размера массива, например:
#define ARRAY_LENGTH 512
const int array [ARRAY_LENGTH ] =
{
MACRO_REPEAT(ARRAY_LENGTH , -2) // this repeats -2, 512 times
[4] = 10,
[5] = 2,
...
}
но это расширяется до MACRO_REPEAT_ARRAY_LENGTH, не расширяется ARRAY_LENGTH
значение перед объединением. Другим примером может быть многомерные массивы, которые включают в себя больше уровней расширение:
#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,
...
}
это расширится до MARO_REPEAT_X * Y. Итак, есть ли способ расширить эти значения до конечного числового значения, прежде чем объединять его с другими макросами?
2 ответов
вы можете решить MACRO_REPEAT(ARRAY_LENGTH , -2)
case путем изменения определения MACRO_REPEAT
для использования расширения 2 этапа, т. е. не используйте вставку токенов в MACRO_REPEAT
сам, вызовите другой макрос, который делает.
не то, что это будет работать только так, как ожидалось, если ARRAY_LENGTH
определяется как маркер одного числа и если есть определение макроса для этого определенного размера.
вы не можете справиться с более общей MACRO_REPEAT(X*Y , -2)
случай со стандартным препроцессором C.
вы можете использовать расширение gcc для инициализации простых массивов:
#define MACRO_REPEAT(n, e) [ 0 ... (n)-1 ] = (e),
но этот метод нельзя использовать для обработки многомерных массивов, таких как MACRO_REPEAT(X*Y , -2)
.
вы можете попробовать это:
#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) }) };
но использование препроцессора C просто запутывает намерение. Если вы решили полагаться на расширения gcc, просто используйте их напрямую.
Я не уверен, что это считается "правильным" ответом, поскольку он не отвечает на вопрос OP напрямую, но это предлагаемое обходное решение проблемы. Он также не является стандартным C, поскольку он использует расширение GCC.
в компиляторе GNU C (gcc) диапазон элементов массива может быть инициализирован с тем же значением, используя форму [FIRST ... LAST] = VALUE
. Он также позволяет использовать более одного назначенного инициализатора для элемента, поэтому можно инициализировать диапазон элементов одинаково value, а затем инициализировать элементы, содержащиеся в этом диапазоне, для разных значений, что-то вроде этого:
#define ARRAY_LENGTH 512
const int array[ARRAY_LENGTH] =
{
[0 ... ARRAY_LENGTH - 1] = -2,
[4] = 10,
[5] = 2,
/* ... */
};