По-прежнему безопасно удалять nullptr в c++0x?


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

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

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

Примечания:

есть значительные косвенные доказательства того, что он все еще хорошо определен.

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

в первом варианте (delete object) значение операнда delete может быть нулевым указателем значение. ,..

и

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

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

во-вторых, изменение смысла delete 0 это серьезное изменение, и Комитет по стандартам вряд ли сделает это конкретное изменение. Кроме того, нет никаких упоминаний о том, что это является критическим изменением в приложении по совместимости (приложение с)c++0x проект. Однако приложение С является информативным разделом, поэтому это не имеет никакого отношения к толкованию стандарта.

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

2 60

2 ответа:

5.3.5/7 говорит:

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

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

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

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

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

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

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

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