C++ 运算符删除和强制转换

C++ 运算符删除和强制转换,c++,C++,我可以像下面的代码一样使用smth吗: int main() { int* foo = new int; double* bar = reinterpret_cast<double*>(foo); delete bar; } intmain() { int*foo=新int; 双*条=重新解释铸件(foo); 删除条; } 是UB吗 我认为我们只需要为操作符new返回的指针调用操作符delete,但是在这种情况下如何进行强制转换呢 我认为这是UB,因为re

我可以像下面的代码一样使用smth吗:

int main()
{
    int* foo = new int;
    double* bar = reinterpret_cast<double*>(foo);
    delete bar;
}
intmain()
{
int*foo=新int;
双*条=重新解释铸件(foo);
删除条;
}
是UB吗

我认为我们只需要为操作符new返回的指针调用操作符delete,但是在这种情况下如何进行强制转换呢

我认为这是UB,因为reinterpret_cast没有对结果指针提供任何保证。我说得对吗

有人能发布标准中正确的引用吗?

§5.3.5/2“在第一个备选方案(删除对象)中,值为 delete的操作数可以是空指针值,也可以是指向 由以前的新表达式创建的非数组对象,或 指向子对象(1.8)的指针,该子对象表示此类对象的基类 一个对象(第10条)。如果不是,则行为未定义
bar
指向一个
double
,它不指向对象 由以前的新表达式(它创建了一个
int
)创建。

这里是:

5.3.5第3点:在第一个备选方案(删除对象)中,如果要删除的对象的静态类型不同于其静态类型 动态类型,静态类型应是要删除的对象的动态类型的基类,并且 静态类型应具有虚拟析构函数或行为未定义

关于什么是静态和动态类型的问题:

1.3.7动态类型(glvalue)
glvalue表达式表示的glvalue引用的最派生对象(1.8)的类型 [示例:如果静态类型为“指向类B的指针”的指针(8.3.1)p指向类的对象 D、 根据B(第10条),表达式*p的动态类型为“D”。参考文件(8.3.2)被处理 类似地。-结束示例]

1.3.23静态类型
在不考虑执行语义的情况下,通过分析程序得到的表达式类型(3.9) [注:表达式的静态类型仅取决于表达式所在程序的形式 显示,并且在程序执行时不会更改。-结束说明]

从5.3.5-3:

在第一个备选方案(删除对象)中,如果 要删除的对象与其动态类型(静态)不同 类型应为待处理对象的动态类型的基类 已删除,静态类型应具有虚拟析构函数或 行为是未定义的

撇开在这里使用
重新解释\u cast
时可能出现的问题不谈,这是UB,因为类型不匹配。想象一下一些非平凡的类型,那么您可以很容易地将其视为调用的“错误”dtor


此外,标准中没有明确规定将
reinterpret\u cast
的结果用于除将其返回外的任何内容。

请注意,此处的UB位于删除表达式中,而不是运算符delete。好的,那么此处的UB呢?你能把标准的报价贴出来吗。(这实际上是我找到答案时正在寻找的段落。)在这种情况下,静态和动态类型是什么?静态类型是指针的类型(
double
)。动态类型是指针对象的类型(
int
)。@Tadeusz Kopec在其他答案中,您与Damon的观点不同。谁是对的?:)@尼基塔托菲莫夫:我在回答中加入了退出标准。它们在注释中的格式不好。在这种情况下,静态和动态类型是什么?
int
double
。但是,即使标准的措辞过于复杂,也不能理解,只需考虑你用你所做的来调用错误的构造函数。这应该是显而易见的,即使没有上述报价。这两个析构函数都是微不足道的,所以它“会起作用”,但它仍然非常明显。@NikitaTrophimov,这里有更多:@Damon在其他答案中,你和Tadeusz Kopec的观点不同。谁是对的?:)@NikitaTrophimov该标准仅在多态对象的情况下区分静态类型和动态类型。在我引用的文本中,没有提到它:它只是列出了三种法律案例:空指针、指向由以前的新表达式创建的对象的指针,以及当由新表达式创建的对象是派生对象时指向基的指针。还有后面指定的其他约束,但在本例中,我们已经失败了。本例中的静态和动态类型是什么?@NikitaTrophimov:对象的动态类型是int,因为对象创建为int,表达式的静态类型是double,在这一点上,你把这件事看成是替罪羊。从其他答案来看,你与其他人的观点不同:)