Стандартная альтернатива трюку GCC ## __ VA_ARGS__?

Существует хорошо известная проблема с пустыми аргументами для вариационных макросов в 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__)

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

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

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

Edit : Вот пример (хотя и простой) того, почему я хотел бы использовать 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 (), что является преимуществом, если запись в журнал буферизирована по строкам и поступает из нескольких источников асинхронно.

140
задан Community 23 May 2017 в 11:47
поделиться