gpt4 book ai didi

c++ - static_cast 从基析构函数到指向派生类的指针的安全性

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:27:08 27 4
gpt4 key购买 nike

这是问题的变体 Downcasting using the Static_cast in C++Safety of invalid downcast using static_cast (or reinterpret_cast) for inheritance without added members

关于 ~B 中的行为,我不清楚标准中的短语“B 实际上是 D 类型对象的子对象,结果指针指向 D 类型的封闭对象”。如果在 ~B 中转换为 D,此时它仍然是子对象吗?以下简单示例显示了问题:

void f(B* b);

class B {
public:
B() {}
~B() { f(this); }
};

class D : public B { public: D() {} };

std::set<D*> ds;

void f(B* b) {
D* d = static_cast<D*>(b); // UB or subobject of type D?
ds.erase(d);
}

我知道转换是一扇通向灾难的大门,从 dtor 做任何类似的事情都是一个坏主意,但一位同事声称“代码是有效的并且工作正常。那个转换是完全有效的。评论明确指出不应取消引用它。”

我指出强制转换是不必要的,我们应该更喜欢类型系统提供的保护而不是注释。可悲的是,他是高级/首席开发人员之一,并且是一个假定的 C++“专家”。

我可以告诉他 Actor 是 UB 吗?

最佳答案

[expr.static.cast]/p11:

A prvalue of type “pointer to cv1 B,” where B is a class type, can be converted to a prvalue of type “pointer to cv2 D,” where D is a class derived (Clause 10) from B, if a valid standard conversion from “pointer to D” to “pointer to B” exists (4.10), cv2 is the same cv-qualification as, or greater cv-qualification than, cv1, and B is neither a virtual base class of D nor a base class of a virtual base class of D. The null pointer value (4.10) is converted to the null pointer value of the destination type. If the prvalue of type “pointer to cv1 B” points to a B that is actually a subobject of an object of type D, the resulting pointer points to the enclosing object of type D. Otherwise, the behavior is undefined.

那么,问题是,在 static_cast 时,指针是否实际指向“a B,它实际上是类型对象的子对象D”。如果是,则没有UB;如果不是,则行为未定义无论结果指针是否被取消引用或以其他方式使用

[class.dtor]/p15 说(强调我的)

Once a destructor is invoked for an object, the object no longer exists

[basic.life]/p1 是这样说的

The lifetime of an object of type T ends when:

  • if T is a class type with a non-trivial destructor (12.4), the destructor call starts, or
  • [...]

从这里开始,D 对象的生命周期在其析构函数被调用时就结束了,当然到 B 的析构函数开始执行时 - 这是在 D 的析构函数主体执行完毕之后。在这一点上,没有“D 类型的对象”留下这个 B 可以是它的子对象 - 它“不再存在”。因此,你有 UB。

Clang 与 UBsan 将 report an error在此代码上,如果 B 是多态的(给定一个虚函数),它支持这种阅读。

关于c++ - static_cast 从基析构函数到指向派生类的指针的安全性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28928590/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com