Где в Стандарте C++ делает он говорит:: удалите может изменить lvalues?

Я столкнулся со своим первым компилятором, который изменяется, lvalue передал:: удалите, но не обнуляйте lvalue. Это следующее, верно:

 Foo * p = new Foo();
 Foo * q = p;
 assert(p != 0);
 assert(p == q);
 ::delete p;
 assert(p != q);
 assert(p != 0);

Обратите внимание, что p не является нулем после удалить операции, и это изменилось от, он - старое значение. Коллега сказал мне, что это весьма обычно, по его опыту, работавший с некоторыми мейнфреймовыми компиляторами C++, которые изменили бы p на 0xFFFFFFFF, а также другие компиляторы, которые изменят p на 0.

Где в Стандарте C++ это говорит, что компилятору позволяют сделать это?

Перерывая StackOverflow, я нашел этот вопрос: Почему не удаляет, устанавливает указатель в NULL? который имел ответ, который упомянул ответ Bjarne Stroustrup, который включает оператор:

C++ явно позволяет реализацию, удаляют для обнуления lvalue операнда, и я надеялся, что реализации сделают это, но та идея, кажется, не стала популярной у реализаторов.

Я считал и перечитал раздел 5.3.5, и 12.5 из заключительного комитета проектируют C++ 0x стандарт, но я не вижу "явную" часть. Я просто смотрю в неправильных разделах стандарта? Или есть ли цепочка логики, которая находится в разделах, но я просто не соединяюсь вместе правильно.

У меня нет своей копии Аннотируемого Справочника C++ больше. Это было в ARM, что компилятор мог сделать это?

[Редактирование: Исправление ссылки раздела от 3.5.3 до 5.3.5. Я также добавляю интересный парадокс как контрапункт к утверждению Henk, что p не определен после того, как удаляют.]

Существует интересный парадокс, если p инициализируется к пустому указателю.

 Foo * p = 0;
 Foo * q = p;
 assert(p == 0);
 assert(p == q);
 ::delete p;
 assert(p == q);
 assert(p == 0);

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

8
задан Community 23 May 2017 в 10:27
поделиться

1 ответ

Возможно, это не так явно. В 5.3.5 / 7 говорится, что выражение удаления вызовет функцию освобождения памяти. Затем в 3.7.3.2/4 говорится, что использование освобожденного указателя не определено. Поскольку значение указателя нельзя использовать после освобождения, то, сохраняет ли указатель значение или значение изменяется реализацией, не имеет значения.

5.3.5/7

Выражение удаления вызовет функцию освобождения (3.7.3.2).

3.7.3.2/4

Если аргумент, переданный функции освобождения в стандартной библиотеке, является указателем, который не является значением нулевого указателя (4.10), функция освобождения освобождает память, на которую ссылается указатель, render - сделать недействительными все указатели, относящиеся к любой части освобожденного хранилища. Эффект от использования недопустимого значения указателя (включая передачу его в функцию освобождения) не определен .

Ссылки взяты из действующего стандарта. В готовящемся к выпуску стандарте 5.3.5 / 7 была изменена формулировка:

C ++ 0x FD 5.3.5 / 7

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

8
ответ дан 5 December 2019 в 20:12
поделиться
Другие вопросы по тегам:

Похожие вопросы: