如何在非对齐位置将char数组转换为int?

时间:2014-11-18 13:09:06

标签: c++ c alignment reinterpret-cast pointer-arithmetic

在C / C ++中是否有办法在任何位置将char数组转换为int?

我尝试了以下内容,如果我尝试使用非const偏移的指针算法,它会自动对齐到最接近的32位(在32位架构上):

unsigned char data[8];
data[0] = 0; data[1] = 1; ... data[7] = 7;
int32_t p = 3;
int32_t d1 = *((int*)(data+3));  // = 0x03040506  CORRECT
int32_t d2 = *((int*)(data+p));  // = 0x00010203  WRONG

更新

  • 如评论中所述,输入的元组为3,而我不能 改变这一点。
  • 我想将3个值转换为int以进一步转换 处理和转换应该尽可能快。
  • 的 解决方案不一定是跨平台的。我正在和一个非常合作 特定的编译器和处理器,因此可以假设它是32 有大端的位结构。
  • 结果的最低字节对我来说无关紧要(见上文)。

目前我的主要问题是:为什么d1值正确但d2不正确?这对其他编译器也是如此吗?这种行为可以改变吗?

2 个答案:

答案 0 :(得分:4)

不,你不能以便携的方式做到这一点。

尝试从char*转换为int*时遇到的行为在C和C ++中都是未定义(可能是因为您发现的原因: int可能在4字节边界上对齐,data当然是连续的。)

data+3有效但data+p不起作用的事实可能是由于编译时间与运行时评估有关。)

另请注意,{C}或C ++中未指定char的签名,因此如果您正在编写此类代码,则应使用signed charunsigned char

最好的办法是使用按位移位运算符(>><<)和逻辑|以及&char值吸收到{{} 1}}。如果您使用16位或64位int来构建目标,请考虑使用int32_t

答案 1 :(得分:2)

没有办法将指针转换为错误对齐的指针是未定义的。

您可以使用memcpychar数组复制到int32_t

int32_t d = 0;
memcpy(&d, data+3, 4); // assuming sizeof(int) is 4

大多数编译器都有memcpy的内置函数和一个常量大小的参数,因此很可能不会产生任何运行时开销。

即使您所显示的强制转换允许使用正确对齐的指针,但取消引用此类指针也会违反严格的别名。无法通过char[]类型的左值访问有效类型为int的对象。

通常,类型 - 双关语依赖于字节顺序,并且转换表示RGB颜色的char数组可能更容易以字节顺序无关的方式进行,例如

int32_t d = (int32_t)data[2] << 16 | (int32_t)data[1] << 8 | data[0];