В чем причина этого неоперируемого цикла while, используемого для макросов assert?

Я рассматриваю кодовую базу, где assert макрос раскрывается следующим образом в не отладочных конфигурациях:

#define assert( what ) while( 0 )( ( void )1 )

что я не совсем понимаю. Очевидно, что цель - не играть. Тогда почему бы не развернуться в пустую строку?

#define assert( what )

В чем причина этого безоперационного цикла?

2 ответа

Решение

Скорее всего, чтобы избежать предупреждений компилятора. Проверьте, вызывает ли этот код предупреждение о пустом утверждении:

if (foo);

Если да, то хотите ли вы такое же предупреждение в режиме выпуска для следующего кода?

if (foo) assert(what);

C99 (который имеет отношение к C++11) также говорит, что assert расширяется "до пустого выражения". IIRC, только пробел не является выражением, хотя пробел, за которым следует точка с запятой, является выражением-выражением. Старая добрая грамматика БНФ.

Кстати, это определение assert не соответствует стандартам. С89 и С99 оба говорят, что когда NDEBUG определяется, тогда assert определяется как:

#define assert(ignore) ((void)0)

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

Сожрать точку с запятой, скорее всего. Нужно это или нет - я не думаю, что это будет иметь большое значение, но в то же время это тоже ничего не повредит.

Другие вопросы по тегам