Уже не раз замечаю подобный код
#if FUSE_TRACE
#define TRACE(x...) fprintf(stderr,x)
#else
#define TRACE(x...) do {} while (0)
#endif
Почему именно так, а не
#if FUSE_TRACE
#define TRACE(x...) fprintf(stderr,x)
#else
#define TRACE(x...)
#endif
Насколько я понял do {} while (0) транслируется в NOP инструкцию, но зачем она здесь?
Ответ
Макросы - вещь достаточно тонкая. Представьте ситуацию, кто-то написал код (пример условный) (но лучше так не пишете именно из-за этого).
for (int i = 0;i < 10; i++)
TRACE("ok"), s+=i;
do_any();
Здесь всё будет корректно работать.
В релиз режиме если мы будем использовать как вы предлагаете
#define TRACE(x...)
Произойдёт следующее, код преобразуется в
if (something)
, s+=i;
do_any();
И он не скомпилируется.
Так же не скомпилируется
expr? TRACE("y") : TRACE("n");
Однако, и с использованием макроса #define TRACE(x...) do {} while (0) есть аналогичные проблемы. Я лично использую следующий макрос в таких целях:
#define TRACE(x...) ((void)0)
Либо же использую отдельную функцию (а не макрос) для вывода логов.
Комментариев нет:
Отправить комментарий