下面是从字节数组中获取int16 (短)值的最有效的方法吗?
inline __int16* ReadINT16(unsigned char* ByteArray,__int32 Offset){
return (__int16*)&ByteArray[Offset];
};如果字节数组包含与机器具有相同字节顺序格式的字节转储,则将调用此代码。我们欢迎其他的选择。
发布于 2011-07-28 14:59:20
只有在你能保证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类型-我建议您也这样做。
发布于 2011-07-28 15:33:20
令我惊讶的是,还没有人提出这样的解决方案,既是对齐安全,又是跨所有架构的正确。(好吧,任何一个字节有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上产生异常。我还记得,当你遇到对齐问题时,SunOS上的Sparc就会彻底崩溃。
发布于 2011-07-28 15:14:38
inline __int16* ReadINT16(unsigned char* ByteArray,__int32 Offset)
{
return (__int16*)&ByteArray[Offset];
}; 不幸的是,这在C++中有未定义的行为,因为您使用两种不同的类型访问存储,这在严格的别名规则下是不允许的。您可以使用char*访问类型的存储,但反之亦然。
根据我之前提出的问题,真正安全的方法是使用memcpy将字节复制到int中,然后使用它。(它很可能会被优化为您希望的相同代码,因此看起来效率非常低)。
你的代码可能会工作,大多数人似乎都会这样做……但重点是,当有一天编译器供应商生成的代码不是你希望的那样时,你不能哭着去找编译器供应商。
https://stackoverflow.com/questions/6855115
复制相似问题