字节数组到C++中的int

Byte array to int in C++

本文关键字:中的 int C++ 字节数 数组 字节      更新时间:2023-10-16

以下是从字节数组中获取int16(短(值的最有效方法吗?

inline __int16* ReadINT16(unsigned char* ByteArray,__int32 Offset){
    return (__int16*)&ByteArray[Offset];
};

如果字节数组包含与机器相同endian格式的字节转储,则会调用此代码。欢迎使用其他方法。

这取决于你所说的"高效"是什么意思,但请注意,在某些体系结构中,如果Offset是奇数,则此方法将失败,因为生成的16位int将错位,并且当你随后尝试访问它时,你会得到一个异常。只有当你能保证Offset是偶数时,才应该使用此方法,例如

inline int16_t ReadINT16(uint8_t *ByteArray, int32_t Offset){
    assert((Offset & 1) == 0); // Offset must be multiple of 2
    return *(int16_t*)&ByteArray[Offset];
};

还要注意的是,我对其进行了轻微的更改,使其直接返回16位值,因为返回指针并随后取消引用它很可能比直接返回16比特值"效率"更低。我还切换到了整数的标准Posix类型——我建议您也这样做。

我很惊讶,还没有人建议在所有架构中使用这一方法来实现对齐安全正确的解决方案。(好吧,任何一个字节有8位的体系结构(。

inline int16_t ReadINT16(uint8_t *ByteArray, int32_t Offset)
{
    int16_t result;
    memcpy(&result, ByteArray+Offset, sizeof(int16_t));
    return result;
};

我想memcpy的开销是可以避免的:

inline int16_t ReadINT16(uint8_t *ByteArray, int32_t Offset)
{
    int16_t result;
    uint8_t* ptr1=(uint8_t*)&result;
    uint8_t* ptr2 = ptr1+1;
    *ptr1 = *ByteArray;
    *ptr2 = *(ByteArray+1);
    return result;
};

我相信对齐问题不会在x86上产生异常。如果我还记得的话,Windows(当它在Dec Alpha和其他平台上运行时(会捕获对齐异常并修复它(性能平平(。我确实记得,当你遇到对齐问题时,SunOS上的Sparc会崩溃。

inline __int16* ReadINT16(unsigned char* ByteArray,__int32 Offset)
{     
    return (__int16*)&ByteArray[Offset]; 
}; 

不幸的是,这在C++中有未定义的行为,因为您使用两种不同的类型访问存储,这在严格的别名规则下是不允许的。您可以使用char*访问某个类型的存储,但不能使用其他方法。

根据我之前提出的问题,唯一安全的方法是使用memcpy将字节复制到int中,然后使用它。(无论如何,它可能会被优化到与您希望的相同的代码,所以看起来效率非常低(。

你的代码可能会工作,而且大多数人似乎都这样做。。。但关键是,当有一天编译器供应商生成的代码没有达到你所希望的效果时,你不能向它哭诉。

我认为这没有问题,这正是我要做的。只要字节数组可以安全访问,并且你确保偏移量是正确的(短路是2个字节,所以你可能想确保它们不能做奇数偏移或类似的事情(