Variadic макросы с 0 аргументами в C99 - PullRequest
10 голосов
/ 26 августа 2010

У меня есть некоторый отладочный код, который выглядит следующим образом:

#define STRINGIFY(x) #x
#define TOSTRING(x) STRINGIFY(x)
#define AT __FILE__ ":" TOSTRING(__LINE__)
void __my_error(const char*loc, const char *fmt, ...);
#define my_error(fmt, ...) __my_error(AT, fmt, ##__VA_ARGS__)

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

my_error("Uh oh!");

Я бы хотел бы мой код C99, поэтому я обнаружил, что при компиляции получаю следующую ошибку:

error: ISO C99 requires rest arguments to be used

Я знаю, что могу решить эту проблему, изменив вызов на

my_error("Uh oh!", NULL);

Но есть ли способ сделать этот вид менее уродливым?Спасибо!

1 Ответ

12 голосов
/ 30 августа 2010

Я вижу два решения этой проблемы. (Три, если вы считаете «придерживаться GCC»).

макрос особого случая

Добавить новый макрос, если вы хотите напечатать фиксированную строку.

#define my_errorf(str) my_error(str, NULL)

Pro : минимальное количество дополнительного кода.
Con: Легко использовать неправильный макрос (но, по крайней мере, вы заметите это во время компиляции).

Поместите fmt в '...'

Макросы Vararg могут иметь только __VA_ARGS__ в качестве параметра (в отличие от функций vararg). Таким образом, вы можете поместить аргумент fmt в __VA_ARGS__ и изменить свою функцию.

void __my_error(const char *loc, ...);
#define my_error(...) __my_error(AT, __VA_ARGS__)

Pro : один синтаксис / макрос для всех сообщений об ошибках.
Con : Требуется переписать вашу функцию __my_error, что может быть невозможно.

...