Ответ 1
Единственная цель сложного выражения (void)0
заключается в том, чтобы избежать предупреждений компилятора. Если у вас просто было обнаженное, бесполезное выражение, компилятор мог бы предупредить о выражении, которое не имеет никакого эффекта. Но, явно наложив что-то на void
, вы укажете, что вы хотите сделать это.
(Подумайте о том, насколько запутанным будет пользователь, если компилятор вдруг сказал: "Предупреждение: выражение 0;
не имеет никакого эффекта". Когда все, что вы сделали, переключается в режим выпуска.)
Это также была распространенная практика в C, где вы могли бы сказать (void)printf("Hello");
сообщить компилятору, что вы намеренно решили игнорировать возвращаемое значение функции.
Приведение (void)
не просто выбор конкретной реализации; это требуется по стандарту C. Цитируя стандарт ISO C 2011 года (аналогичная формулировка представлена в изданиях 1990 и 1999 годов):
Если
NDEBUG
определяется как имя макроса в точке исходного файла где<assert.h>
включен, макросassert
определяется просто как
#define assert(ignore) ((void)0)
Стандарт С++ требует, чтобы содержимое заголовка <cassert>
совпало с заголовком Standard C <assert.h>
.