【问题标题】:Operator delete and casting运算符删除和强制转换
【发布时间】:2013-06-24 19:43:47
【问题描述】:

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

int main()
{
    int* foo = new int;
    double* bar = reinterpret_cast<double*>(foo);
    delete bar;
}

是UB吗?

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

我认为它是 UB,因为 reinterpret_cast 不对结果指针提供任何保证。我说的对吗?

有人可以从标准中发布正确的报价吗?

【问题讨论】:

  • 注意这里的UB在于delete表达式,而不是操作符delete。
  • 好的,那么这里的 UB 呢?你能把标准的报价贴出来吗?

标签: c++


【解决方案1】:

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

【讨论】:

  • 这种情况下静态类型和动态类型分别是什么?
  • intdouble,分别。但是,即使标准的措辞过于复杂而无法理解,只要考虑到您正在使用您所做的事情调用错误的构造函数。即使没有上述引用,这也应该是显而易见的。这两个析构函数都是微不足道的,所以它“会起作用”,但它仍然很明显是 UB。
  • @NikitaTrophimov,更多:stackoverflow.com/questions/1347691/…
  • @Damon 在其他答案中,您的观点与 Tadeusz Kopec 不同。谁是对的? :)
  • @NikitaTrophimov 该标准仅在多态对象的情况下区分静态和动态类型。在我引用的文本中,没有提及它:它仅列出了三种合法情况:空指针,指向由先前的 new 表达式创建的对象的指针,以及当 new 表达式创建的对象时指向 Base 的指针-表达式是派生的。还有一些额外的限制,稍后会指定,但在这种情况下,我们在这里已经失败了。
【解决方案2】:

从 5.3.5-3:

在第一种选择(删除对象)中,如果是静态类型的 要删除的对象与其动态类型不同,静态 type 应该是对象的动态类型的基类 已删除且静态类型应具有虚拟析构函数或 行为未定义。

抛开在此处使用reinterpret_cast 可能出现的问题,这是UB,因为类型不匹配。想象一些非平凡的类型,然后你可以很容易地看到这是因为会调用“错误”的 dtor。

除了将reinterpret_cast 的结果用于其他任何事情之外,标准大多未指定。

【讨论】:

  • 这种情况下静态类型和动态类型分别是什么?
  • @NikitaTrophimov:对象的动态类型是 int,因为对象是作为 int 创建的,而表达式的静态类型是 double,因为此时您将事物视为 double。跨度>
  • 你和其他答案的人有不同的意见:)
【解决方案3】:

你在这里:

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)的类型 [注:表达式的静态类型只取决于表达式所在的程序的形式 出现,并且在程序执行时不会改变。 ——尾注]

【讨论】:

  • 还有。 (这实际上是我找到答案时正在寻找的段落。)
  • 这种情况下静态类型和动态类型分别是什么?
  • 静态类型是指针的类型(double)。动态类型是指针的类型(int)。
  • @Tadeusz Kopec 在其他答案中,您与 Damon 的意见不同。谁是对的? :)
  • @NikitaTrophimov 我在我的答案中添加了标准中的相当。他们不会在评论中很好地格式化。
猜你喜欢
  • 1970-01-01
  • 2017-03-29
  • 1970-01-01
  • 1970-01-01
  • 2023-03-20
  • 1970-01-01
  • 2014-10-07
  • 2019-05-15
  • 1970-01-01
相关资源
最近更新 更多