Я выполняю задачу по изменению текущего механизма ведения журнала в моей кодовой базе CPP.
Текущий - это что-то вроде printf, в котором мы можем написать
MYLOGGING(("Example Log :%s, Example Num: %d", String, Number));
Теперь, как часть его изменения к новому механизму ведения журнала, я хочу получить этот полный вывод в строку, используя snprintf(). Для этого я использовал список переменных для этого.
Код был похож
#define MYLOGGING(log_string,...) do { \
char buff[1024]; \
memset(buff, 0, sizeof(buff)); \
snprintf(buff, sizeof(buff), log_string, ##__VA_ARGS__); \
MYNEW_LOG(NewlogParams, buff); \
} while(0)
Теперь я столкнулся с проблемой. В существующем журнале было много экземпляров, в которых некоторые значения перечисления печатаются с использованием простого% d. В таких случаях с этим новым кодом он выдает следующую ошибку.
error: невозможно преобразовать 'enumType в' const char * для аргумента '3 в' int snprintf (char *, size_t, const char *,...)
Один очевидный вариант, чтобы избавиться от этого - дать целочисленный тип casting для распечаток enum.
Поскольку это может быть утомительным процессом, мне любопытно узнать, могу ли я исправить это каким-то другим способом?
Пожалуйста, поделитесь своими взглядами.
Заранее спасибо.
__VA_ARGS__
оператор ##
в __VA_ARGS__
, вы превращаете параметры формата в const char *
:
snprintf(buff, sizeof(buff), log_string, ##__VA_ARGS__);
Измените это на:
snprintf(buff, sizeof(buff), log_string, __VA_ARGS__);
и преобразование должно работать.
На самом деле, внимательно посмотрев на ваш вопрос, я заметил еще одну проблему. Оператор ##
действительно необычен и, вероятно, неверен, однако главной причиной вашей проблемы, по-видимому, являются дополнительные парнеры в вызове MYLOGGING
MYLOGGING(("Example Log :%s, Example Num: %d", String, Number));
Если вы компилируете вызов этого макроса в GCC с флагом -E
для вывода предварительно обработанного источника, вы получите эту строку, расширенную из макроса:
do { char buff[1024]; memset(buff, 0, sizeof(buff)); snprintf(buff, sizeof(buff), ("Example Log :%s, Example Num: %d", String, Number)); ....
Вы можете видеть, что ()
все еще там, перепутав вызов snprintf
. Поэтому удалите оба ##
в макросе и дополнительные парсеры на сайте вызова.