gpt4 book ai didi

c++ - static_cast 向下转换实际上不是对象类型的类型是未定义的行为吗?

转载 作者:行者123 更新时间:2023-11-30 00:44:17 27 4
gpt4 key购买 nike

这是一个 discussion on stackoverflow四种显式转换中的一种。但我在投票最多的答案中遇到了一个问题。

引用自投票最多的 wiki 答案:

static_cast can also cast through inheritance hierarchies. It is unnecessary when casting upwards (towards a base class), but when casting downwards it can be used as long as it doesn't cast through virtual inheritance. It does not do checking, however, and it is undefined behavior to static_cast down a hierarchy to a type that isn't actually the type of the object.

但是在cppref ,我读了一些不那么严肃的东西:
static_cast < new_type > ( expression )

If new_type is a pointer or reference to some class D and the type of expression is a pointer or reference to its non-virtual base B, static_cast performs a downcast. This downcast is ill-formed if B is ambiguous, inaccessible, or virtual base (or a base of a virtual base) of D. Such static_cast makes no runtime checks to ensure that the object's runtime type is actually D, and may only be used safely if this precondition is guaranteed by other means.

所以在 cppref 中它没有说undefined behavior,而是说not safe 不太严重。

所以当我做类似的事情时:

class A{virtual foo(){}};
class B:public A{};
class C:public B{};
int main()
{
C*pc=new C;
A*pa=static_cast<A*>(pc);//Ok,upcast.
B*pb=static_cast<B*>(pa);//downcast,**is it undefined or just not safe?**
C* pc1=static_cast<C*>(pb);//downcast back to C;
}

还有一个问题,如果不是UB,取消引用是不是UB pb

最佳答案

cppreference 是用英文写的,目的是为了传达良好的理解,它实际上并不是规范。但我对这里的措辞没有问题:

Such static_cast makes no runtime checks to ensure that the object's runtime type is actually D, and may only be used safely if this precondition is guaranteed by other means.

如果你保证前提条件,就可以了。如果您不保证前提条件,那么您的代码就不安全。代码不安全意味着什么?它的行为没有定义。

实际规范使用this wording :

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.


无论哪种方式,在您的示例中,您的所有转换都是有效的。

B*pb=static_cast<B*>(pa);//downcast,**is it undefined or just not safe?**

您缺少条件。沮丧本身并不是未定义的行为。如果那里实际上没有派生类型的对象,那只是未定义的行为。在这种情况下,pa 指向 C,它是 B,因此转换为 B是安全的。

然而,这不是:

struct B { };
struct D1 : B { };
struct D2 : B { };

B* p = new D1;
static_cast<D2*>(p); // undefined behavior, no D2 object here

关于c++ - static_cast 向下转换实际上不是对象类型的类型是未定义的行为吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49399783/

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