Страницы

Поиск по вопросам

понедельник, 12 ноября 2018 г.

Для чего делать do {} while (0)?

Уже не раз замечаю подобный код
#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)
Либо же использую отдельную функцию (а не макрос) для вывода логов.

Комментариев нет:

Отправить комментарий