Расширение макроса C на несколько определений функций - PullRequest
0 голосов
/ 18 октября 2019

У меня есть 3 очень похожих функции журнала, которые будут вызываться из разных мест.

void INFO (char *format, ...) {
   char log_buf[256] = {0};
   va_list args;
   va_start(args, format);
   vsprintf(log_buf, format, args);
   va_end(args);
   LIB_LOG_INFO(log_buf);
}

void ERROR (char *format, ...) {
   char log_buf[256] = {0};
   va_list args;
   va_start(args, format);
   vsprintf(log_buf, format, args);
   va_end(args);
   LIB_LOG_ERROR(log_buf);
}

void DEBUG (char *format, ...) {
   char log_buf[256] = {0};
   va_list args;
   va_start(args, format);
   vsprintf(log_buf, format, args);
   va_end(args);
   LIB_LOG_DEBUG(log_buf);
}

Я не могу передать никаких дополнительных аргументов, поэтому я не могу выполнить if-else для вызова различных функций LIB_LOG.

Можно ли написать общий макрос, который расширится до этих трех определений функций во время компиляции? Только имена функций LIB_LOG отличаются.

1 Ответ

2 голосов
/ 18 октября 2019

Прежде всего, обратите внимание, что функции с переменными аргументами, в частности, почти наверняка являются неправильным решением любой проблемы. Их следует рассматривать как устаревшую, опасную функцию - избегайте их, если это возможно.

Как говорится, вы можете решить свою проблему, создав единую универсальную функцию, которая принимает параметр указателя функции:

typedef void lib_log_func_t (char* buf);

void lib_log (lib_log_func_t* func, const char* format, ...)
{
  char log_buf[256] = {0};
  va_list args;
  vsprintf(log_buf, format, args);
  va_end(args);
  func(log_buf);
}

Затем напишите 3 макроса-оболочки:

#define INFO(format, ...)  lib_log(LIB_LOG_INFO,  format, __VA_ARGS__)
#define ERROR(format, ...) lib_log(LIB_LOG_ERROR, format, __VA_ARGS__)
#define DEBUG(format, ...) lib_log(LIB_LOG_ERROR, format, __VA_ARGS__)
...