我可以像下面的代码一样使用smth:
int main()
{
int* foo = new int;
double* bar = reinterpret_cast<double*>(foo);
delete bar;
}
是UB吗?
我认为我们只需要为operator new返回的指针调用operator delete,但在这种情况下怎样才能进行转换?
我认为它是UB,因为reinterpret_cast不会对结果指针提供任何保证。我是对的吗?
有人可以从标准中发布正确的引用吗?
答案 0 :(得分:6)
§5.3.5/ 2“在第一个备选(删除对象)中,值为
delete的操作数可以是空指针值,指向的指针
由前一个new-expression创建的非数组对象,或
指向表示此类基类的子对象(1.8)的指针
一个对象(第10条)。如果没有,行为是不确定的。“从那以后
bar
指向double
,它不指向对象
由前一个新表达式(创建int
)创建。
答案 1 :(得分:2)
从5.3.5-3开始:
在第一个替代(删除对象)中,如果是静态类型的 要删除的对象不同于其动态类型,静态 type应该是对象的动态类型的基类 删除和静态类型应具有虚拟析构函数或 行为未定义。
除了在这里使用reinterpret_cast
时可能出现的问题外,这是UB,因为类型不匹配。想象一下一些非常重要的类型,然后你可以很容易地看到这个,因为“错误”的dtor会被调用。
此外,除了将reinterpret_cast
的结果用于其他任何内容之外,其他任何内容都不会被标准化。
答案 2 :(得分:0)
你在这里:
5.3.5第3点:在第一个备选(删除对象)中,如果要删除的对象的静态类型与其不同 动态类型,静态类型应该是要删除的对象的动态类型的基类 静态类型应具有虚拟析构函数或行为未定义。
关于什么是静态和动态类型的问题:
1.3.7动态类型(glvalue)
由glvalue表达式表示的glvalue所指向的最派生对象(1.8)的类型 [例如:如果指针(8.3.1)p的静态类型是“指向B类的指针”,则指向类的对象 D,源自B(第10条),表达式* p的动态类型是“D”。参考文献(8.3.2)被处理 与此类似。 - 例子]1.3.23静态类型
在不考虑执行语义的情况下对程序进行分析得到的表达式(3.9)的类型 [注意:表达式的静态类型仅取决于表达式所在程序的形式 出现,并且在程序执行时不会更改。 - 后注]