Это зависит от типа msize
.
Если msize
является указателем, он проверяет, является ли это NULL
.
Если msize
не является указателем, он проверяет, является ли это 0
.
Это различие может показаться педантичным, но это важно. В то время как NULL
на самом деле 0
на большинстве систем, стандарт C позволяет ему быть любым другим значением.
Я прочитал несколько дальнейших чтений, потому что я начал сомневаться в правильности моего понимания выше.
Ниже приведены соответствующие части стандарта C.
§6.5.3.3 Унарные арифметические операторы
(5) В результате логической операции отрицания !
равно 0, если значение ее операнда сравнивает равно 0, 1, если значение его операнда сравнивает , равный 0. Результат имеет тип int
. Выражение !E
равнозначно до (0==E)
.
§6.3.2.3 Указателей
(3) Константа выражения целого числа со значением 0, или такого выражением преобразованных к типу void *
, называется пустого указателя постоянной.) Если константный указатель NULL преобразуется в тип указателя, полученный указатель, называемым пустого указателя, гарантированно сравнить с неравными указателя на любой объект или функцию.
(6) Любой тип указателя может быть преобразован в целочисленный тип. За исключением описанного ранее , результат определяется реализацией. Если результат не может быть представлен в целочисленном типе, поведение не определено. Результат не должен быть в диапазоне значений любого целого числа .
Сноска: Макроса NULL
является де определен в <stddef.h> (и другие заголовки) в качестве нулевого указателя постоянная; см. 7.19.
Как вы можете видеть, 0 является своим родом магического числа в C. Для систем с ненулевым NULL
, я ожидаю, что реальное поведение !msize
может быть от реализации. В любом случае, это все немного придирчиво.
Я выследил источник вашего примера в документе: Undefined Behavior: What Happened to My Code?. Текст обсуждения ваш пример гласит:
Как уже упоминалось ранее, на уровне набора команд, x86 поднимает исключение для деления на ноль [17, 3.2], в то время как MIPS [22, А.6] и PowerPC [15, 3.3.38] молча игнорирует его. Деление на ноль в C равно неопределенного поведения [19, 6.5.5], и поэтому компилятор может просто принять , что делитель всегда отличен от нуля.
На рисунке 1 показано злоупотребление делением на нуль в ядре Linux. Из комментария программиста ясно, что целью является сигнализация ошибки в случае, если msize равен нулю. При компиляции с GCC этот код ведет себя как предполагалось на x86, но не на PowerPC, потому что он будет не генерировать исключение. При компиляции с Clang результатом является еще более удивительным. Clang предполагает, что делитель msize должен быть ненулевым - на любой системе, так как иначе деление не определено. В сочетании с этим допущением нулевая проверка! Msize всегда равна false, так как msize не может быть как нулевым, так и ненулевым. Компилятор определяет, что весь блок кода недостижим и удаляет его, , который имеет неожиданный эффект от удаления оригинального программиста намерения защитить от случая, когда msize равен нулю.
Так что в вашем случае ответ вам действительно нужен был да: он проверяет, соответствует ли msize
0.
Там нет никакой разницы между 0 и NULL в большинстве систем. – AndyG