У меня есть макрос ведения журнала и функция, и я хотел бы, чтобы они имели одно и то же имя, чтобы, когда я пропускаю заголовок с макросом, программа все равно строилась (через объявление C неявной функции ).
Я пытался:
/* Declare function. */
void logmsg(const char *fmt, ...) __attribute__((format(printf, 1, 2)));
/* Declare macro (with the same name). */
#define logmsg(fmt, ...) \
logmsg(fmt, ##__VA_ARGS__)
Однако это не удается с ошибкой компиляции:
In file included from util.c:53:
../lib/util.h:296:13: error: expected identifier or ‘(’ before ‘do’
296 | do { if (1) (logmsg(fmt, ##__VA_ARGS__)); } while (0)
| ^~
util.c:248:6: note: in expansion of macro ‘logmsg’
248 | void logmsg(const char *fmt, ...)
| ^~~~~~
../lib/util.h:296:59: error: expected identifier or ‘(’ before ‘while’
296 | do { if (1) (logmsg(fmt, ##__VA_ARGS__)); } while (0)
| ^~~~~
util.c:248:6: note: in expansion of macro ‘logmsg’
248 | void logmsg(const char *fmt, ...)
Как я могу достичь своей цели?
ИЗМЕНИТЬ:
Я решил проблему с помощью косвенная ссылка идентификатора макроса на самого себя, например:
void logmsg(const char *fmt, ...) __attribute__((format(printf, 1, 2)));
#define log_impl(specarg, fmt, ...) \
logmsg(fmt,##__VA_ARGS__)
#define logmsg(fmt, ...) \
log_impl(msg,fmt,##__VA_ARGS__)
Аргумент msg
для log_impl()
скорее не нужен, но я спрятал код и не могу проверить его, чтобы быть уверенным.