GCC Extensions
GCC имеет расширение для обработки этого (обратите внимание на пропущенную запятую перед ...
):
Неправильно (ссылки __VA_ARGS__
, что не разрешено в расширении GCC):
#define RDF_LOG(dbglevel, fmt ...) (rdfDBG(dbglevel, " " fmt, __VA_ARGS__))
Правильно (без ссылки __VA_ARGS__
):
#define RDF_LOG(dbglevel, fmt...) (rdfDBG(dbglevel, " " fmt))
void rdfDBG(int dbglevel, const char *fmt, ...) { /* printf debug message */ }
enum { kERROR };
void x(const char *pinfile);
void x(const char *pinfile)
{
RDF_LOG(kERROR, "Fail to open file %s\n", pinfile);
RDF_LOG(kERROR, "Insufficient Memory\n");
}
Вы можете сказать, что я не использую расширение GCC - потому что я использую некоторые компиляторы, которые не являются GCC.
Существует также второй (специфичный для GCC) механизм, упомянутый Адамом в его комментарии:
#define RDF_LOG(dbglevel, fmt, ...) (rdfDBG(dbglevel, " " fmt, ## __VA_ARGS__))
void rdfDBG(int dbglevel, const char *fmt, ...) { /* printf debug message */ }
enum { kERROR };
void x(const char *pinfile);
void x(const char *pinfile)
{
RDF_LOG(kERROR, "Fail to open file %s\n", pinfile);
RDF_LOG(kERROR, "Insufficient Memory\n");
}
Стандарт C99
В противном случае вы должны использовать стандартный механизм C99:
#define RDF_LOG(dbglevel, ...) (rdfDBG(dbglevel, " " __VA_ARGS__))
void rdfDBG(int dbglevel, const char *fmt, ...) { /* printf debug message */ }
RDF_LOG(kERROR, "Fail to open file %s\n", pinfile); /* Call 1 */
RDF_LOG(kERROR, "Insufficient Memory\n");
Это в основном обманывает или обходит проблему для этого контекста. В общем случае C99 требует запятую и хотя бы один аргумент.