#pragma внутри #define

Я работаю в микроконтроллере с помощью языка C. В этом конкретном микро, прерывания должны быть определены с помощью #pragma следующим способом:

static void func();
#pragma INTERRUPT func <interrupt_address> <interrupt_category>
static void func() { /* function body */ }

<interrupt_address> адрес прерывания в таблице векторов. <interrupt_category> или 1 или 2. Например, для определения прерывания в Порте 0 контактов 0:

static void _int_p00();
#pragma INTERRUPT _int_p00 0x10 1
static void _int_p00() { (*isr_p00)(); }

Мы определяем фактическую процедуру обработки прерывания в другом месте и используем указатель функции (как isr_p00 в примере) для выполнения их.

Было бы удобно, если прерывания могли бы быть определены с помощью макроса. Я хочу, действительно определяют макрос следующим способом:

#define DECLARE_INTERRUPT(INT_NAME, INT_CAT) \
    static void _int_##INT_NAME(); \
    #pragma INTERRUPT _int_##INT_NAME INT_NAME##_ADDR INT_CAT \
    static void _int_##INT_NAME() { (*isr_##INT_NAME)(); }

Компилятор, бросающий следующую ошибку:

Formal parameter missing after '#'

указание после строки:

static void _int_##INT_NAME() { (*isr_##INT_NAME)(); }

Я предполагаю, что директивы препроцессору не могут использоваться в #defines? Есть ли вокруг какая-либо работа?

10
задан Brian Tompsett - 汤莱恩 26 February 2016 в 13:35
поделиться

3 ответа

В C99 есть новое ключевое слово _Pragma , которое позволяет размещать #pragma внутри макросов. Обычно он ожидает строку в качестве аргумента, который соответствует тексту, который вы должны передать директиве #pragma .

Если ваш компилятор не поддерживает это (gcc поддерживает), и вы бы выбрали внешнюю реализацию того, что вам нужно (как сказано, m4 может быть выбором), лучше всего, вероятно, будет оставайтесь как можно ближе к не очень новому _Pragma . Затем, как только ваш конструктор компилятора догонит стандарт, вы можете просто прекратить использовать свой скрипт.

13
ответ дан 3 December 2019 в 23:10
поделиться

Насколько мне известно, то, что вы конкретно просите, невозможно. Я предполагаю, что препроцессор работает так же, как Препроцессор GNU C . В руководстве для этого указано :

Компилятор не повторно токенизирует вывод препроцессора. Каждый токен предварительной обработки становится одним токеном компилятора.

0
ответ дан 3 December 2019 в 23:10
поделиться

Выход - использовать генерацию кода или другой макроязык для предварительной обработки кода.

т.е. писать код с другим расширением.

Пусть ваш makefile или подобная программа вызовет макроязык (например, m4) или скрипт какой-либо формы для создания .c-файла

Затем скомпилируйте его.

1
ответ дан 3 December 2019 в 23:10
поделиться
Другие вопросы по тегам:

Похожие вопросы: