在我的代码中,我实际上有以下内容:
wchar_t* buffer = new wchar_t[size];
// bonus irrelevant code here
delete[] reinterpret_cast<char*>( buffer );
所涉及的类型都是内置的,因此它们具有简单的析构函数。在 VC++ 中,上面的代码工作正常 -new[]
只是分配内存,然后delete[]
只是释放它。
在C++中可以接受吗?这是未定义的行为吗?
我最初的想法是这是未定义的行为。
5.3.5/3: "In the second alternative (delete array) if the dynamic
type of the object to be deleted
differs from its static type, the
behavior is undefined.73).
脚注 73 写道:“这意味着不能使用类型的指针删除对象void*
因为没有类型的对象void
".
可以说你的例子中的对象没有have动态类型,因为 1.3.3 中“动态类型”的定义提到了“最派生对象”,而 1.8/4 中“最派生对象”的定义谈论的是类类型的对象。所以我一直在寻找:
5.2.10/3:“[reinterpret_cast] 可能会也可能不会产生一个表示
与原始值不同”
5.3.5/2:“操作数的值delete
应为指针值
这是由先前的数组产生的
新表达式”。
我不确定 reinterpret_cast 是否会产生与输入相同的指针值。可能它被我还没有找到的其他一些标准所清除。如果没有找到明确的说明,如果你reinterpret_cast一个指针,结果是与之前相同的“指针值”,我不会称这段代码为“OK”,这样通过将它传递给delete[],你就传递了“指针值” “来自新[]。
5.2.10/7:“除了[在某些指针类型之间]和
回到其原始类型产生
原始指针值,结果
这样的指针转换是
未指定”。
这对我来说似乎是个坏消息 - 它显然没有说转换产生相同的值,只是说这对来回转换产生相同的值。这对我来说意味着单次强制转换可以产生不同的值,但这只是暗示性的,而不是明确的。这是“如果标准没有说明行为,则行为未定义”规则的常见问题。仅仅因为它没有在我可以使用索引找到的任何段落中说明它,并不意味着它没有在其他地方说明它......
我们知道,在实践中,我们可以将内容强制转换为 unsigned char* 以便检查其字节,或者使用 void* 来使用 memcpy 复制 POD,因此必须有一些强制转换来保证创建别名。您可能会认为,如果您的实现确实创建了具有某些强制转换的别名,那么您将传入从 new[] 获得的“相同值”。但我仍然不确定这对于删除[]来说是否足够好。我想我错过了一些重要的事情。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)