【问题标题】:static_cast VS reinterpret_cast when casting pointers to pointers将指针转换为指针时的 static_cast VS reinterpret_cast
【发布时间】:2021-09-09 05:15:26
【问题描述】:

鉴于以下条件:

struct A
{
    int a;
};

struct B
{
    int b;
};

int main()
{
    A  a {1};
    A* p = &a;

使用static_castreinterpret_cast 通过void* 进行投射是否会产生相同的结果?即以下表达式之间有什么区别?

    static_cast      <A*> ( static_cast      <void*> (p) );
    reinterpret_cast <A*> ( reinterpret_cast <void*> (p) );

如果我们使用static_castreinterpret_cast 将指向一个类的指针转换为指向另一类的指针会怎样?这两个运营商有什么区别吗?以下表达式是否相同?

    static_cast      <B*> ( static_cast      <void*> (p) );
    reinterpret_cast <B*> ( reinterpret_cast <void*> (p) );
    reinterpret_cast <B*> (                           p  );

我可以在这之后使用B* 指针来访问b 成员吗?

【问题讨论】:

    标签: c++ reinterpret-cast static-cast


    【解决方案1】:

    下面的表达方式有区别吗?

    static_cast      <A*> ( static_cast      <void*> (p) );
    reinterpret_cast <A*> ( reinterpret_cast <void*> (p) );
    

    没有。

    下面的表达是一样的吗?

    static_cast      <B*> ( static_cast      <void*> (p) );
    reinterpret_cast <B*> ( reinterpret_cast <void*> (p) );
    reinterpret_cast <B*> (                           p  );
    

    是的。

    理解这一点的简单方法是考虑如何指定从指针到指针的 reinterpret_cast。 reinterpret_cast&lt;T*&gt;(ptr) 被指定为与 static_cast&lt;T*&gt;(static_cast&lt;void*&gt;(ptr)) 完全相同(为简单起见,我省略了 cv 限定符)。

    当然,static_cast&lt;T&gt;(static_cast&lt;T&gt;(anything)) 等价于 static_cast&lt;T&gt;(anything),因为外部强制转换始终是身份转换。


    我可以在这之后使用 B* 指针来访问 b 成员吗?

    没有。如果你这样做了,那么程序的行为将是不确定的。

    【讨论】:

    • 值得一提的是,从pB* 的转换并不总是等同于首先转换到void*——它只是用于OP 的示例.如果AB 在层次上相关,则指针值可以作为转换的一部分而改变。另外,从A -&gt; void -&gt; B AFAIK 转换始终是取消引用的未定义行为,而A -&gt; B 可以是合法的,前提是两种类型是布局兼容的
    • 为了完整性,我认为值得一提的标准是:“8.5.1.10 重新解释强制转换:7 对象指针可以显式转换为不同类型的对象指针。当prvalue v 的对象指针类型转换为对象指针类型“指向cv T的指针”,结果为static_cast(static_cast(v))。"
    • @Human-Compiler A and B were hierarchically related, the pointer value can change as part of the cast.static_cast&lt;A*&gt;(b_ptr) 的情况下,是的。如果没有继承,那么该演员阵容将是不正确的。 Plus, casting from A -&gt; void -&gt; B AFAIK is always undefined behavior to dereference, whereas A -&gt; B can be legal provided two types are layout-compatible 如果您的意思是 reinterpret_cast 并且这些转换是指针,那么这两个在各个方面都是相同的,并且无论布局兼容性如何,访问都是 UB。如果您的意思是 static_cast,那么后者可能是明确定义的。
    • @Human-Compiler 关于If A and B were hierarchically related, the pointer value can change as part of the cast 从技术上讲,指针值可以在大多数类型转换中更改为另一种类型(甚至不是分层静态或动态转换),因为通常不需要指针类型除特殊情况外,具有相同的代表性。所有指针通常在实践中确实具有相同的表示,例如在 64 位 x86 上。
    • @eerorika 给定struct Coordinate{double x, double y, double z}; double *ptr1, *ptr2; Coordinate stSpaceCoord; ptr1 = static_cast&lt;void*&gt;(&amp;stSpaceCoord);ptr2 = reinterpret_cast&lt;void*&gt;(&amp;stSpaceCoord); 之间有什么区别?谢谢。
    猜你喜欢
    • 1970-01-01
    • 2012-10-24
    • 1970-01-01
    • 2017-02-12
    • 1970-01-01
    • 2021-07-26
    • 2021-09-20
    • 1970-01-01
    相关资源
    最近更新 更多