为什么不 reinterpret_cast 强制 copy_n 用于相同大小类型之间的强制转换? [英] Why Doesn't reinterpret_cast Force copy_n for Casts between Same-Sized Types?

查看:24
本文介绍了为什么不 reinterpret_cast 强制 copy_n 用于相同大小类型之间的强制转换?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

根据 cppreference.comreinterpret_cast:

通过重新解释底层位模式在类型之间进行转换.

Converts between types by reinterpreting the underlying bit pattern.

但是等等,这是一个谎言,因为它只在这些情况下有效:

But wait, that's a lie cause it only works in these cases:

T1 类型的对象的指针或引用是 reinterpret_cast(或 C 风格强制转换)时,指向不同类型 的对象的指针或引用T2,强制转换总是成功,但结果指针或引用只有在 T1T2 都是标准布局类型和以下之一时才能访问为真:

  • T2 是对象的(可能是 cv 限定的)动态类型
  • T2T1 都是(可能是多级的,可能在每一级都有 cv 限定)指向相同类型的指针 T3
  • T2 是对象动态类型的(可能是 cv 限定的)有符号或无符号变体
  • T2 是聚合类型或联合类型,将上述类型之一作为元素或非静态成员(递归地包括子聚合的元素和非静态数据成员)包含联合):这使得从结构的第一个成员和从联合的元素到包含它的结构/联合的转换是安全的.
  • T2 是对象动态类型的(可能是 cv 限定的)基类
  • T2charunsigned char
  • When a pointer or reference to object of type T1 is reinterpret_cast (or C-style cast) to a pointer or reference to object of a different type T2, the cast always succeeds, but the resulting pointer or reference may only be accessed if both T1 and T2 are standard-layout types and one of the following is true:

    • T2 is the (possibly cv-qualified) dynamic type of the object
    • T2 and T1 are both (possibly multi-level, possibly cv-qualified at each level) pointers to the same type T3
    • T2 is the (possibly cv-qualified) signed or unsigned variant of the dynamic type of the object
    • T2 is an aggregate type or a union type which holds one of the aforementioned types as an element or non-static member (including, recursively, elements of subaggregates and non-static data members of the contained unions): this makes it safe to cast from the first member of a struct and from an element of a union to the struct/union that contains it.
    • T2 is a (possibly cv-qualified) base class of the dynamic type of the object
    • T2 is char or unsigned char

    根据该列表,一个非法示例是:

    According to that list an illegal example would be:

    auto foo = 13LL;
    auto bar = reinterpret_cast<double&>(foo);
    

    因此,唯一可以接受的制作该演员表的方法是复制内存:

    So the only acceptable way to make that cast is to copy the memory:

    auto foo = 13LL;
    double bar;
    
    copy_n(reinterpret_cast<char*>(&foo), sizeof(foo), reinterpret_cast<char*>(&bar));
    

    我的问题是,为什么 reinterpret_cast 不为我处理这个问题?还是有其他可用的东西,所以我不必跳过这个圈子?

    My question is, why doesn't reinterpret_cast handle that for me? Or is there something else available so I don't have to jump through this hoop?

    推荐答案

    为什么 reinterpret_cast 不为我处理?

    一个原因是没有指定大小、对齐方式和位表示,因此这样的转换是不可移植的.但是,这并不能证明使行为未定义,只是实现定义的合理性.

    One reason is that the size, alignment, and bit representations aren't specified, so such a conversion wouldn't be portable. However, that wouldn't really justify making the behaviour undefined, just implementation-defined.

    通过使其未定义,允许编译器假定不相关类型的表达式不会访问同一个对象,这可以实现更好的优化.例如,在下面:

    By making it undefined, the compiler is allowed to assume that expressions of unrelated types don't access the same object, which can allow better optimisation. For example, in the following:

    int   & i = something();
    float & f = something_else();
    
    const int i1 = i;
    f = 42;
    const int i2 = i;
    

    编译器可以假设 i1i2 都具有相同的值(i 通过分配给 f),并将它们优化为单个常量.打破假设将导致未定义的行为.

    the compiler can assume that i1 and i2 both have the same value (i being unchanged by the assignment to f), and optimise them into a single constant. Breaking the assumption will then cause undefined behaviour.

    或者还有其他可用的东西,所以我不必跳过这个圈子?

    Or is there something else available so I don't have to jump through this hoop?

    复制字节是将一个对象类型重新解释为不相关类型的唯一明确定义的方法.

    Copying the bytes is the only well-defined way to reinterpret one object type as an unrelated type.

    使用 reinterpret_cast 或联合的别名有时可能会起作用(假设大小等匹配),但如果优化器对未定义的行为过于聪明,则可能会绊倒您.

    Aliasing with reinterpret_cast or a union might work sometimes (assuming the size etc. match), but might trip you up if the optimiser gets too clever with undefined behaviour.

    这篇关于为什么不 reinterpret_cast 强制 copy_n 用于相同大小类型之间的强制转换?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆