Препроцессор C генерирует макросы путем конкатенации и строкового преобразования [duplicate]
На этот вопрос уже есть ответ здесь:
Какие приложения оператора ## препроцессора и ошибки должны быть рассмотрены? 13 ответовУ меня есть набор целевых макросов, для которых я хочу генерировать псевдонимы на основе выбранного макроса, например:
Выбор макроса:
#define I2C_MODULE 1
Макросы псевдонимов (концептуальная форма):
#define I2C_MODULE_BASE I2C<Value of I2C_MODULE>_BASE
#define I2C_MODULE_NVIC INT_I2C<Value of I2C_MODULE>
Целевые макросы (из внешнего файла вне моего контроля):
#define INT_I2C0 24
#define INT_I2C1 53
...
#define I2C0_BASE 0x40020000
#define I2C1_BASE 0x40021000
...
Я хотел, чтобы препроцессор генерировал макросы псевдонимов.I2C_MODULE_BASE
а такжеI2C_MODULE_NVIC
на основе выбора макросаI2C_MODULE
, но после долгих чтенийQ1, P1 и многие другие ссылки, которые я потерял, закончились жестким кодированием их значений. Ниже я показываю мои текущие рабочие определения, а затем мои последние неудачные попытки генерации макросов:
Что работает:
#define I2C_MODULE 1
#define I2C_MODULE_BASE I2C1_BASE
#define I2C_MODULE_NVIC INT_I2C1
что не сработало
#define I2C_MODULE 1
#define STR_HELPER(x) #x
#define STR(x) STR_HELPER(x)
/* Attempt 1 */
#define I2C_MODULE_BASE "I2C" STR(I2C_MODULE) "_BASE"
#define I2C_MODULE_NVIC "INT_I2C" STR(I2C_MODULE)
/* Attempt 2 */
#define _I2C_MODULE_BASE "I2C" STR(I2C_MODULE) "_BASE"
#define _I2C_MODULE_NVIC "INT_I2C" STR(I2C_MODULE)
#define I2C_MODULE_BASE _I2C_MODULE_BASE
#define I2C_MODULE_NVIC _I2C_MODULE_NVIC
РЕДАКТИРОВАТЬ: я расширил напринятый ответ чтобы добраться туда, где я хотел, следующим образом:
#define PASTE2(a, b) a ## b
#define PASTE3(a, b, c) a ## b ## c
#define _I2C_MODULE_BASE(x) PASTE3(I2C, x, _BASE)
#define _I2C_MODULE_NVIC(x) PASTE2(INT_I2C, x)
#define I2C_MODULE_BASE _I2C_MODULE_BASE(I2C_MODULE)
#define I2C_MODULE_NVIC _I2C_MODULE_NVIC(I2C_MODULE)