Подтвердить что ты не робот

Вызов delete на NULL-указателях - С++ 03 vs С++ 11

В стандарте С++ 03 я вижу:

5.3.5 Удаление

2 Если операнд имеет тип класса, операнд преобразуется в тип указателя, вызывая вышеупомянутую функцию преобразования, а преобразованный операнд используется вместо исходного операнда для остальной части этого раздела. В любом другом случае, если значение операнда delete является нулевым указателем, операция не имеет эффекта. В первом альтернативе (объект удаления) значение операнда delete должно быть указателем на объект без массива или указатель на под-объект (1.8), представляющий базовый класс такого объекта (раздел 10). Если нет, то поведение undefined. Во втором альтернативе (удалить массив) значение операнда delete должно быть значением указателя, которое было получено из предыдущего массива new-expression.72) Если нет, то поведение undefined.

В Стандартном проекте С++ 11 (N3337) я вижу:

5.3.5 Удаление

2 Если операнд имеет тип класса, операнд преобразуется в тип указателя, вызывая вышеупомянутую функцию преобразования, а преобразованный операнд используется вместо исходного операнда для остальной части этого раздела. В первом альтернативе (удалить объект) значение операнда delete может быть значением нулевого указателя, указателем на объект без массива, созданный предыдущим новым выражением, или указатель на подобъект (1.8), представляющий базовый класс такого объекта (раздел 10). Если нет, то поведение undefined. Во втором альтернативе (удалить массив) значение операнда удаления может быть значением нулевого указателя или значением указателя, которое было результатом предыдущего нового выражения. Если нет, поведение undefined.

Я выделил различия между спецификациями в двух стандартах. Мне показалось странным, что стандарт 2003 года был более решительным в отношении того, как нужно указывать указатели NULL, в то время как в стандарте 2011 года ничего не говорится о том, что должна делать реализация.

  • Изменилось ли словосочетание стандарта С++ 11 между стандартом проекта и фактическим стандартом? Если да, то как?

  • Если формулировка проекта стандарта остается неизменной в фактическом стандарте, что послужило основанием для изменения очень сильного заявления почти ничего с 2003 по 2011 год?

4b9b3361

Ответ 1

Похоже, мы можем найти обоснование для этого изменения в отчете о дефекте 348, в котором говорится:

В частности, стандарт говорит в пункте 5.3.5 [expr.delete]:

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

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

Кроме того, в параграфе 4 стандарт говорит о дефолтной функции дефолта:

Если выражение-выражение вызывает освобождение реализации   function (3.7.4.2 [basic.stc.dynamic.deallocation]), если операнд   выражение delete не является константой нулевого указателя,...

Почему это так специфично при взаимодействии функции дезактивации по умолчанию и delete-expr?

Если "не имеет эффекта" является требованием к функции освобождения, тогда это должно быть указано в 3.7.4.2 [basic.stc.dynamic.deallocation] или в 18.6.1.1 [new.delete.single] и 18.6.1.2 [new.delete.array], и это должно быть указано явно.

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

Ответ 2

Последний проект С++ 14 (N3797) имеет примерно эквивалентную формулировку в этом разделе. Но поведение одинаково строго указано, просто не в том же абзаце.

Если значение операнда выражения-удаления не является нулевым значение указателя, выражение delete вызовет деструктор (если any) для объекта или элементов удаляемого массива. в случай массива, элементы будут уничтожены в порядке (то есть в обратном порядке завершения их конструктор; видеть 12.6.2).

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

Эти параграфы явно так же сильны, как С++ 03. Комитет не мог нарушить поведение программ, в которых delete нулевые указатели, поскольку они широко распространены, а стоимость исправления будет слишком большой. Это сделало бы С++ 11 незаменимым.