И этот вопрос включал обоснование того, что FOO не использовался целую вечность.

твуетобщеизвестный проблема с пустыми аргументами для variadic макросов в C99.

пример:

#define FOO(...)       printf(__VA_ARGS__)
#define BAR(fmt, ...)  printf(fmt, __VA_ARGS__)

FOO("this works fine");
BAR("this breaks!");

ИспользованиеBAR() выше действительно неверно в соответствии со стандартом C99, так как он расширится до:

printf("this breaks!",);

Обратите внимание на запятую - не работает.

Некоторые компиляторы (например, Visual Studio 2010) спокойно избавятся от этой запятой для вас. Другие компиляторы (например: GCC) поддерживают установку## перед__VA_ARGS__, вот так:

#define BAR(fmt, ...)  printf(fmt, ##__VA_ARGS__)

Но есть ли совместимый со стандартами способ получить такое поведение? Возможно, используя несколько макросов?

Прямо сейчас## версия кажется достаточно хорошо поддерживаемой (по крайней мере, на моих платформах), но я бы предпочел использовать совместимое со стандартами решение.

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

редактироватьВот пример (хотя и простой) того, почему я хотел бы использовать BAR ():

#define BAR(fmt, ...)  printf(fmt "\n", ##__VA_ARGS__)

BAR("here is a log message");
BAR("here is a log message with a param: %d", 42);

Это автоматически добавляет новую строку в мои операторы ведения журнала BAR (), предполагая,fmt всегда C-строка в двойных кавычках. Он НЕ печатает новую строку как отдельную функцию printf (), что выгодно, если регистрация ведется с буферизацией строки и поступает из нескольких источников асинхронно.

Ответы на вопрос(10)

Ваш ответ на вопрос