Несовместимое преобразование типа аргумента с помощью макроса - PullRequest
1 голос
/ 24 апреля 2020

Я пытаюсь использовать один аргумент макроса (предоставленный третьей стороной) для отображения строки с заполнителями и значениями этих заполнителей.

#define DBG1(AR1)    do{             \
                        printf(AR1); \
                     }while(0);

int main()
{
  int varDummy = 123;

  /* Expecting Test Message 123*/
  DBG1(("Test Message %d\r\n", varDummy));

  return 0;
}

Обратите внимание на аргумент DBG1 («Тестовое сообщение% d \ r \ n», varDummy) в скобках и обрабатывается как целая строка, то есть const char *, а ошибка показывает, что varDummy не разрешено преобразовывать из-за его тип int.

В фактическом коде аргумент DBG1 имеет различное количество заполнителей (% d,% x ...) и соответствующие значения, которые должны быть напечатаны. По-видимому, я не могу отобразить переданную строку вместе со значениями ее заполнителя.

В реальном коде у меня есть следующий макрос от третьей стороны

LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d, %p, %"SZT_F", 0x%x, ..)\n", s, mem, len, flags));

/* discarding the first argument */
#define LWIP_DEBUGF(debug, message) do{                 \
                                        DBG1(message)   \
                                     }while(0);

Обратите внимание, что это ресурс ограничен встроенная система.

Ответы [ 3 ]

0 голосов
/ 24 апреля 2020

Обратите внимание, что аргумент DBG1 заключен в круглые скобки

Да, это проблема, вы вызываете printf(("Test Message %d\r\n", varDummy));, когда внутренние скобки превратили , из разделителя аргументов функции в оператор запятой. Оператор запятой отбрасывает левый операнд и возвращает правый. Это int, тип несовместимый со строкой формата printf, которая объясняет ошибку компилятора.

Вместо этого вам следует использовать макрос variadi c:

#define DBG1(AR1,...) printf(AR1, __VA_ARGS__)
...
DBG1("Test Message %d\r\n", varDummy);

В этом случае использовать трюк do-while (0) бессмысленно.


Обратите внимание, что это встроенная система с ограниченными ресурсами.

Тогда вы в первую очередь не следует использовать функции stdio.h или variadi c. Вместо этого создайте свой собственный модуль ведения журнала продукта-специфика c. Написание небольшого фрагмента, который выплевывает строки в UART, - это не ракетостроение.

Аналогично, анализ необработанных двоичных данных из UART также не является ракетостроением, так что вам на самом деле не нужно преобразование строк, просто Приличная терминальная программа на P C.

0 голосов
/ 24 апреля 2020

Обратите внимание на аргумент DBG1 («Тестовое сообщение% d \ r \ n», varDummy) в скобках…

Эта проблема является одновременно решением. Поскольку скобки уже есть, вам не нужно указывать их в макросе DBG1, и вы можете изменить printf(AR1); \ на printf AR1; \. Кроме того, вы можете упростить макрос до

#define DBG1(AR1)   printf AR1;

(поскольку вы не можете изменить макрос LWIP_DEBUGF от стороннего , мы, к сожалению, должны оставить точку с запятой).

0 голосов
/ 24 апреля 2020

Вы можете использовать временный буфер для хранения присоединенной строки, что-то вроде этого:

#define DBG1(AR1) do{\
                  printf(AR1);\
                  } while(0)
#define BUFFER_SIZE 100

int main()
{
    int varDummy = 123;
    char buffer[BUFFER_SIZE];

    sprintf(buffer, "Test Message %d\r\n", varDummy);
    /* Expecting Test Message 123*/
    DBG1(buffer);

    return 0;
}
...