#pragma inside #define - PullRequest
       19

#pragma inside #define

10 голосов
/ 27 июля 2010

Я работаю в микроконтроллере, использующем язык 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)(); }

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

Ответы [ 3 ]

13 голосов
/ 27 июля 2010

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

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

1 голос
/ 27 июля 2010

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

т.е. написать код с другим расширением.например, m4) или сценарий некоторой формы для создания файла .c

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

0 голосов
/ 27 июля 2010

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

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

...