Я столкнулся с моим первым компилятором, который изменяет lvalue, переданное на :: delete, но не обнуляет 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? , ответ на который ссылается на ответ Бьярна Страуструпа , который включает в себя утверждение:
C ++ явно разрешает реализацию delete для обнуления операнда lvalue, и я надеялся, что реализации сделают это, но эта идея, похоже, не стала популярной среди разработчиков.
Я прочитал и перечитал разделы 5.3.5 и 12.5 проекта окончательного комитета стандарта C ++ 0x , но я не вижу "явной" части. Я просто смотрю в неправильные разделы стандарта? Или есть цепочка логики, которая есть в разделах, но я просто не соединяюсь должным образом.
У меня больше нет моей копии Справочного руководства по С ++. Было ли это в ARM, что компилятор мог сделать это?
[Редактировать: Исправление ссылки на разделы с 3.5.3 по 5.3.5. Я также добавляю интересный парадокс в качестве контрапункта к утверждению Хенка о том, что после удаления p не определено.]
Существует интересный парадокс, если p инициализируется нулем.
Foo * p = 0;
Foo * q = p;
assert(p == 0);
assert(p == q);
::delete p;
assert(p == q);
assert(p == 0);
В этом случае поведение хорошо документировано. Когда delete получает нулевой указатель, предполагается, что ничего не происходит, поэтому p остается неизменным.