Литье 0 в пустоту

Возможный дубликат:
Почему (void) 0 a нет операции в C и С++?

В моей реализации С++ (реализация Visual Studio 2008) я вижу следующую строку в <cassert>

#ifdef  NDEBUG
#define assert(_Expression) ((void)0)

Я не понимаю, нужно ли отбрасывать 0 в пустоту. Мне кажется, что

#ifdef  NDEBUG
#define assert(_Expression) (0)

или даже просто

#ifdef  NDEBUG
#define assert(_Expression) 0

учитывая контексты, в которых может использоваться assert(expr).

Итак, какова опасность 0 типа int вместо 0 типа void в этом случае? Любые реалистичные примеры?

Ответ 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>.