我遇到了我的第一个编译器,它更改了传递给 ::delete 的左值,但没有将左值清零。即以下情况属实:
Foo * p = new Foo();
Foo * q = p;
assert(p != 0);
assert(p == q);
::delete p;
assert(p != q);
assert(p != 0);
请注意,删除操作后 p 不为零,并且它已从旧值更改。一位同事告诉我,在他使用一些将 p 更改为 0xFFFFFFFF 的大型机 C++ 编译器以及将 p 更改为 0 的其他编译器的经验中,这并不罕见。
C++ 标准中的什么地方说允许编译器执行此操作?
通过StackOverflow搜索,我发现了这个问题:为什么不删除将指针设置为NULL?其中有一个答案提到了Bjarne Stroustrup 的回应,其中包括以下声明:
C++ 明确允许删除的实现将左值操作数清零,我曾希望实现能够做到这一点,但这个想法似乎并没有在实现者中流行。
我已经阅读并重新阅读了最终委员会草案 C++0x 标准的第 5.3.5 和 12.5 节,但我没有看到“显式”部分。我只是在查看标准的错误部分吗?或者这些部分是否存在逻辑链,但我只是没有正确连接在一起。
我不再拥有 Annotated C++ Reference Manual 的副本。编译器可以在ARM中执行此操作吗?
[编辑:将部分参考从 3.5.3 更正为 5.3.5。我还添加了一个有趣的悖论作为 Henk 断言 p 在删除后未定义的对立面。]
如果将 p 初始化为 null,则会出现一个有趣的悖论。
Foo * p = 0;
Foo * q = p;
assert(p == 0);
assert(p == q);
::delete p;
assert(p == q);
assert(p == 0);
但是,在这种情况下,该行为是有据可查的。当 delete 得到一个空指针时,它应该什么都不做,所以 p 保持不变。