我可以像下面的代码一样使用smth吗:
int main()
{
int* foo = new int;
double* bar = reinterpret_cast<double*>(foo);
delete bar;
}是UB吗?
我认为我们只需要为new返回的指针调用delete操作符,但在这种情况下强制转换又如何呢?
我认为它是UB,因为reinterpret_cast不会对结果指针提供任何保证。我说的对吗?
有没有人能贴出标准中的正确引述?
发布于 2013-06-24 19:28:12
§5.3.5/2“在第一种选择(delete对象)中,delete操作数的值可以是空指针值,指向由先前new表达式创建的非数组对象的指针,或指向表示此类对象基类的子对象(1.8)的指针(第10条)。如果不是,则行为未定义。”因为bar指向一个double,所以它不指向由前一个new-expression (创建了一个int)创建的对象。
发布于 2013-06-24 19:29:12
从5.3.5到3:
在第一种选择(删除对象)中,如果要删除的对象的静态类型与其动态类型不同,则静态类型应为要删除的对象的动态类型的基类,并且静态类型应具有虚拟析构函数或行为未定义。
抛开在这里使用reinterpret_cast时可能出现的问题不谈,这是UB,因为类型不匹配。想象一下一些非平凡的类型,那么您可以很容易地看到这一点,因为“错误的”dtor将被调用。
此外,将reinterpret_cast的结果用于任何其他用途,而不是将其转换回来,这在标准中基本上是未指定的。
发布于 2013-06-24 19:28:38
您的位置如下:
5.3.5第3点:在第一种选择(删除对象)中,如果要删除的对象的静态类型与其动态类型不同,则静态类型必须是要删除的对象的动态类型的基类,并且静态类型必须有一个虚析构函数或行为未定义。
至于什么是静态类型和动态类型的问题:
1.3.7动态类型(GL值)
由glvalue表达式表示的glvalue引用的最派生对象(1.8)的类型示例:如果静态类型为“指向类B的指针”的指针(8.3.1) p指向从B派生的类D的对象(第10条),则表达式*p的动态类型为“D”。引用(8.3.2)的处理方式与此类似。-end示例
1.3.23静态类型
表达式的类型(3.9)是通过分析程序而不考虑执行语义得到的注意:表达式的静态类型仅取决于出现表达式的程序的形式,并且在程序执行时不会改变。-end笔记
https://stackoverflow.com/questions/17274236
复制相似问题