Безопасно ли удалить nullptr в c ++ 0x?

В c++03 совершенно ясно, что удаление нулевого указателя не имеет никакого эффекта. Действительно, в §5.3.5/2 прямо указано, что:

В любом случае, если значением операнда удаления является нулевой указатель, операция не имеет никакого эффекта.

Однако в текущем проекте для c++0x это предложение отсутствует . В остальной части черновика я смог найти только предложения, в которых говорится, что произойдет, если операнд delete-expression не является константой нулевого указателя. Удаление нулевого указателя все еще определено в c++0x, и если да, то где?

Примечания:

Существуют значительные косвенные доказательства, позволяющие предположить, что это понятие все еще четко определено.

Во-первых, в §5.3.5/2 есть два предложения, в которых говорится, что

В первой альтернативе (объект удаления) значение операнда удаления может быть значением нулевого указателя, ...

а также

Во втором варианте (массив удаления) значение операнда удаления может быть значением нулевого указателя или ...

Они говорят, что операнду разрешено быть нулевым, но сами по себе не определяют, что произойдет, если это так.

Во-вторых, изменение значения delete 0 является серьезным изменением, и комитет по стандартам вряд ли внесет это конкретное изменение. Более того, нет упоминания о том, что это критическое изменение в Приложении совместимости (Приложение C) проекта c++0x. Приложение C, однако, является информативным разделом, поэтому оно не имеет никакого отношения к интерпретации стандарта.

С другой стороны, тот факт, что удаление нулевого указателя не должно иметь никакого эффекта, подразумевает дополнительную проверку во время выполнения. Во многих кодах операнд никогда не может быть нулевым, поэтому эта проверка во время выполнения противоречит принципу нулевых накладных расходов. Возможно, комитет просто решил изменить поведение, чтобы привести стандартный c ++ в большее соответствие с заявленными целями дизайна языка.


person Mankarse    schedule 18.07.2011    source источник


Ответы (2)


5.3.5 / 7 говорит:

Если значение операнда выражения удаления не является значением нулевого указателя, выражение удаления вызовет функцию освобождения (3.7.4.2). В противном случае не указано, будет ли вызываться функция освобождения.

И 3.7.4.2/3 говорит:

Значение первого аргумента, предоставленного функции освобождения, может быть значением нулевого указателя; если это так, и если функция освобождения предоставлена ​​в стандартной библиотеке, вызов не имеет никакого эффекта.

Таким образом, поведение четко определено, если используется стандартная функция освобождения или предоставленная пользователем функция освобождения правильно обрабатывает нулевые указатели.

person interjay    schedule 18.07.2011
comment
Начиная с C ++ 14 Если выражение оценивается как значение нулевого указателя, деструкторы отсутствуют вызываются, а функция освобождения не вызывается. - person Wormer; 28.08.2017
comment
@Wormer Я не думаю, что это правильная страница. Стандарт C ++ 14 по-прежнему говорит, что не определено, будет ли вызываться функция освобождения при нулевом указателе (5.3.5 / 7). - person interjay; 28.08.2017
comment
Кстати, небезопасно вызывать fclose () для нулевого указателя файла. В Ubuntu (и, возможно, в других операционных системах) fclose (NULL) вызывает ошибку сегментации. - person Gerry Beauregard; 07.10.2018

С другой стороны, тот факт, что удаление нулевого указателя не должно иметь никакого эффекта, подразумевает дополнительную проверку во время выполнения.

Новая формулировка не удаляет эту проверку времени выполнения для нулевого указателя. С другой стороны: черновой вариант стандарта даже ближе к тому, чтобы сказать, что реализация должна сделать тест нулевого указателя на соответствие.

Также примечательно: старый стандарт противоречил сам себе тем, что в нем говорилось (5.3.5 / 2), что «если значение операнда удаления является нулевым указателем, операция не имеет никакого эффекта», но позже сказал, что (5.3.5 / 7) «выражение-удаление вызовет функцию освобождения». Вызов функции - это эффект. Это особенно верно, поскольку вызываемая функция вполне может быть переопределенной operator delete.

Новая формулировка устраняет это противоречие, явно оставляя на усмотрение реализации вопрос о том, вызывается ли функция освобождения в случае удаления нулевого указателя.

person David Hammen    schedule 18.07.2011