Чи все ще безпечно видаляти nullptr у c ++ 0x?


84

Тут c++03цілком зрозуміло, що видалення нульового вказівника ніяк не впливає. Справді, прямо зазначено, §5.3.5/2що:

В будь-якому варіанті, якщо значення операнда delete є нульовим покажчиком, операція не впливає.

Тим НЕ менше, в поточному проекті для c++0xцієї пропозиції , здається, відсутня. В решті чернетки я міг знайти лише речення, що вказують, що відбувається, якщо операнд виразу delete не є константою нульового покажчика. Видалення нульового покажчика все ще визначено в c++0x, і якщо так, то де?

Примітки:

Існують суттєві побічні докази, які свідчать про те, що він все ще добре визначений.

По-перше, є два речення, в яких §5.3.5/2зазначено, що

У першому варіанті (об'єкт видалення) значення операнда видалення може бути нульовим значенням покажчика, ...

і

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

Вони кажуть, що операнду дозволено мати нульовий характер, але самі по собі насправді не визначають, що трапиться, якщо це буде.

По-друге, зміна значення поняття « delete 0серйозна зміна», і комітет зі стандартів навряд чи зробить цю конкретну зміну. Крім того, немає жодної згадки про те, що це надзвичайна зміна у Додатку про сумісність (Додаток С) c++0xпроекту. Однак Додаток С є інформаційним розділом, тому це не має ніякого тлумачення стандарту.

З іншого боку, той факт, що видалення нульового вказівника потрібно, щоб не мати ефекту, передбачає додаткову перевірку часу виконання. У багатьох кодах операнд ніколи не може бути нульовим, тому ця перевірка виконання суперечить принципу нульових накладних витрат. Можливо, комітет просто вирішив змінити поведінку, щоб привести стандартний c ++ більше у відповідність із заявленими цілями дизайну мови.

Відповіді:


101

5.3.5 / 7 говорить:

Якщо значення операнда виразу delete не є нульовим значенням покажчика, вираз delete буде викликати функцію звільнення (3.7.4.2). В іншому випадку не визначено, чи буде викликана функція звільнення.

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

Значення першого аргументу, що надходить до функції звільнення, може бути нульовим значенням покажчика; якщо так, і якщо функція звільнення є функцією, яка надається у стандартній бібліотеці, виклик не має ефекту.

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


9
Оскільки C ++ 14 "Якщо вираз отримує значення нульового покажчика, деструктори не викликаються, а функція звільнення не викликається."
Wormer

2
@Wormer Я не думаю, що ця сторінка правильна. Стандарт C ++ 14 все ще говорить, що "не визначено, чи буде викликана функція звільнення", коли вказівник нульовий (5.3.5 / 7).
інтержой

1
Як і в стороні, це НЕ безпечно викликати fclose () для покажчика порожнього файлу. На Ubuntu (і, можливо, інших операційних системах), fclose (NULL) викликає помилку сегментації.
Gerry Beauregard

7

З іншого боку, той факт, що видалення нульового вказівника потрібно, щоб не мати ефекту, передбачає додаткову перевірку часу виконання.

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

Також примітно: Старий стандарт суперечив собі тим, що він сказав (5.3.5 / 2), що "якщо значення операнда delete є нульовим покажчиком, операція не впливає", але пізніше сказав, що (5.3.5 / 7) "вираз delete буде викликати функцію звільнення." Виклик функції - це ефект. Це особливо так, оскільки викликана функція цілком може бути заміненою operator delete.

Нове формулювання усуває це протиріччя, явно залишаючи за реалізацією, чи буде викликана функція звільнення у разі видалення нульового вказівника.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.