Безопасно ли всегда опускать проверку указателя NULL перед вызовом Удалить или Удалить[], особенно при написании межплатформенных разделов кода?
Я помню, что несколько лет назад (три или четыре) тот же код, который я написал, работал в MS Windows (скомпилирован с помощью инструментария MSVCv12), но версия, скомпилированная для Linux с g ++ (к сожалению, я не помню версию g ++), выдавала ссылку на указатель NULL. Я нашел информацию, что в то время это, вероятно, была ошибка компилятора.
Я нашел этот SO поток, но, прочитав его, я все еще не совсем уверен, безопасно ли это, и если да, то из какой версии стандарта C++?
"Я нашел информацию, что в то время это, вероятно, была ошибка компилятора." Как компилятор может проверить, что удаляемый указатель является nullptr, и выдать для него ошибку?
@ AlgirdasPreidžius Уверен, что они имели в виду "ошибку компилятора".
Правильно, я имел в виду «ошибку компилятора», а не «ошибку компилятора». Прошу прощения за свою ошибку.
используйте умный указатель или вектор, и вам больше не нужно беспокоиться об удалении слова
Я вспоминаю пару ОЧЕНЬ старых компиляторов C++ (примерно с 1992 года), в которых delete (any_type *)NULL или delete [] (any_type *)NULL вызывали ошибку времени выполнения. Но оба этих компилятора (или их библиотеки) были исправлены в следующем выпуске, предположительно из-за отчетов об ошибках. Я не знаю ни одного компилятора более позднего, чем 1995 год, который неправильно работает с delete NULL, т.е. не имеет никакого эффекта. В современных компиляторах сбой при любом использовании оператора delete, включая delete NULL, обычно является признаком ДРУГОГО предыдущего кода в программе, демонстрирующего неопределенное поведение.





Да, стандарт, начиная с C++ 98, гарантирует, что delete или delete[] на нулевой указатель не действуют.
С ++ 98 §5.3.5 / 2
” In either alternative, if the value of the operand of
deleteis the null pointer the operation has no effect.
Так было и до появления первого стандарта, когда язык был определен в Аннотированном справочном руководстве.
Касательно
” version compiled for Linux with g++ (unfortunately, I do not remember the g++ version) was throwing NULL pointer reference
Это невозможно обсуждать без конкретного и, желательно, полного примера, воспроизводящего поведение. Это не имело ничего общего с удалением нулевого указателя.
есть одна небольшая деталь о C++ 11 и более поздних версиях: не указано, вызывается ли функция освобождения или нет, если указатель имеет значение null, поэтому было бы небезопасно, если функция освобождения повторно реализована пользователем таким образом, чтобы это могло вызвать ошибку или UB если указатель равен nullptr. Но это случай, когда нужно изготовить грабли и после этого наступить на них.
@Swift - operator delete и operator delete[] необходимы для разумной обработки нулевых указателей. «Требуется: [аргумент указателя] должен быть нулевым указателем или его значение должно быть значением, возвращенным более ранним вызовом [оператора new]». [new.delete.single], повторяется в [new.delete.array]. Если вы замените оператор delete, вы заметите, что ваша версия может быть вызвана с нулевым указателем.
@PeteBecker Я знаю это, но некоторые нет. Были вопросы об этом на SO. Я просто отметил это как источник небезопасного поведения в дополнение к довольно хорошему и одобренному ответу. Дело в том, что когда мы пишем delete, это выражение delete, которое будет полагаться на оператор delete, предоставленный пользователем, если он есть. Как и в случае с компилятором нового выражения, он действует как посредник. Некоторые воображают, что компилятор пытается это исправить, а ISO оставляет это неопределенным.
что значит «выбросить ссылку на NULL-указатель»?