使用重新解释强制转换时交换字节序

Swapping endians when using reinterpret cast

本文关键字:转换 交换 字节 新解释 解释      更新时间:2023-10-16

当通过网络发送数据时,可以通过多种方式实现字节数据的转换:

12345  --> {0 0 48 57}
typedef unsigned char byte;
//1. Bit shift
int32_t shiftedInteger =  (int32_t) (inBytes[0] << 24 | inBytes[1] << 16  | 
inBytes[2] << 8 | inBytes[3]);
//2. Reinterpret cast
int32_t reinterpretedInteger = *reinterpret_cast<int32_t*>(&inBytes);
//3. Using unions
union{
    byte b[4];
    int32_t i;
}unionCast;
memcpy(unionCast.b,inBytes,4);
int_32t unionCasted = unctionCast.i;

哪种是转换数据的首选方法(在像微型孔器这样的arduino上使用(?

联合和重新解释 Cast 方法面临大端与小端的问题,但一旦使用浮点数,就会派上用场,因为简单的位移不足以将数据转换回来。使用reinterpret_cast时如何交换字节序?

您使用重新解释和访问不活跃的工会成员都违反了标准。 这样说的规则被称为严格别名。

因此,在您的选项中,换档是唯一符合标准的选项。

另一个选项 - memcpy 直接进入目标类型 - 也符合标准。

你可以合法地通过memcpy到堆栈阵列,放置新的bew tyoe,然后memcpy回来。 优化器将消除内存!

您甚至可以这样做:

template<class T> 
struct raw_bytes:
  std::array<char, sizeof(T)>
{
  static_assert(std::is_pod<T>::value, "pod only");
  static raw_bytes to_raw( T in ){
    raw_bytes r;
    std::memcpy( r.data(), std::addressof(in), sizeof(T) );
    return r;
  }
  // this object no longer valid after convert, but returned reference is until this object destroyed
  T& convert(){
    char tmp[sizeof(T)];
    memcpy(tmp, data(), sizeof(T));
    T* r= ::new( (void*)data() ) T;
    memcpy(r, tmp, sizeof(T));
    return *r;
  }
};

这可能值得,也可能不值得。

您可以将raw_bytes粘贴到结构中,并将字节写入其中。 然后,您可以将这些字节就地convert()T 。 返回的引用是合法访问这些字节的唯一方法;在严格阅读标准的情况下,raw_bytes方法不再合法。

你不能。Reinterprert 强制转换仅更改编译器使用的类型,不会触及数据。

如如何在C++中的大端和小端值之间转换中建议的?用

int32_t __builtin_bswap32 (int32_t x)