В чем причина этого неоперируемого цикла 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)
Я не уверен, считают ли авторы это важным требованием, но программа может, например, упорядочить расширение макроса и ожидать определенного результата.
Сожрать точку с запятой, скорее всего. Нужно это или нет - я не думаю, что это будет иметь большое значение, но в то же время это тоже ничего не повредит.