Получение «Ошибка: # 28: выражение должно иметь постоянное значение» при использовании макроса varidic

0

Я работаю над программированием HW. Я создал ниже макрос Varidic.

#define UPDATE_DATA(bit,...) {  \
do { \
int i; \
int j = 0; \
int _args[] = {__VA_ARGS__};\
int *addr = (int *) ADDR ; \
for (i = 0; i < (sizeof(_args)/sizeof(_args[0])); i++) {\
 *(int *) (DATA_ADDR - j) |= _args[i];\
  j = j + 0x4; \
}\
*addr |= 1 << bit;\
 }while (0); \
}

его работа, если я использую как UPDATE_DATA(1,2,3); Но если использовать этот макрос внутри цикла, например,

msg_id = MSG_1;
for(j=0; j<15 ; j++)
{
  msg_id = msg_id +1;
  l_data = data_array[j];
  UPDATE_DATA(msg_id,l_data,(SYSTEM_BASE_ADDR6+offset));  
  offset = (offset + 0x4);
}

Я получаю сообщение об Error: #28: expression must have a constant value LOGGER_UPDATE_DATA(msg_id,l_data,(SRAM0_SYSTEM_BASE_ADDR6+offset));

Я не понимаю, что я сделал неправильно здесь!

  • 0
    здесь я ошибаюсь int _args[] = {__VA_ARGS__}; в старом кл.
  • 0
    @BLUEPIXY не получил тебя?
Показать ещё 3 комментария
Теги:
macros

1 ответ

1
Лучший ответ

Мое предложение состоит в том, чтобы не использовать переменный макрос. Они расширяют размер кода и затрудняют обслуживание.

Предполагая, что вам не нужно передавать -1 в качестве значения, вы можете использовать stdarg.h

#include <stdio.h>  // for test output, not actually needed when you do the I/O
#include <stdarg.h>

#define LOGGER  ((volatile int *)0x1234)
#define LOGGER_DATA ((volatile int *)0x5678)

void sendToLoggerV(int bit, va_list ap)
{
    int i, value;

    for (i = 0; ; ++i)
    {
        // do your write here...

        value = va_arg(ap, int);
        if (value == -1)
            break;

        // Can't really write it in this test, but this is what you would do:
        //LOGGER_DATA[-i] = value;

        printf("Pretending to write %d to %p\n", value, (void*)&LOGGER_DATA[-i]);
    }
    //*LOGGER |= 1 << bit;
    printf("Pretending to OR %d to %p\n", 1<<bit, (void*)LOGGER);
}

void sendToLogger(int bit, ...)
{
    va_list ap;
    va_start(ap,bit);
    sendToLoggerV(bit, ap);
    va_end(ap);
}

#define SEND_TO(bit, ...) sendToLogger(bit, __VA_ARGS__, -1)

int main()
{
    SEND_TO(1, 16, 17, 18, 19);
    SEND_TO(2, 30, 31);
}

Поскольку это будет работать во встроенной системе, мой тестовый пример просто печатает сообщения, чтобы сказать, что он будет делать. Строки, прокомментированные, будут записывать фактическую память. Я использовал надуманные адреса (0x1234 и 0x5678) для ваших адресов ввода-вывода с отображением памяти.

Этот код выводит следующее, которое соответствует вашим требованиям:

Pretending to write 16 to 0x5678
Pretending to write 17 to 0x5674
Pretending to write 18 to 0x5670
Pretending to write 19 to 0x566c
Pretending to OR 2 to 0x1234
Pretending to write 30 to 0x5678
Pretending to write 31 to 0x5674
Pretending to OR 4 to 0x1234
  • 0
    Спасибо .. это работает гладко :)
  • 0
    Привет, Даг. Снова нужна твоя помощь ... Я знаю, что это было давно ... Я пытался связаться с тобой в чате, где мы обсуждали это, но эта комната, кажется, уже десятка ... Жду твоего ответа !!!

Ещё вопросы

Сообщество Overcoder
Наверх
Меню