char[] 到 uint32_t 无法正常工作

char[] to uint32_t not working properly

我正在使用以下方法将 char[4] 转换为 uint32_t

frameSize = (uint32_t)(frameSizeBytes[0] << 24) | (frameSizeBytes[1] << 16) | (frameSizeBytes[2] << 8) | frameSizeBytes[3];

frameSize 是一个 uint32_t 变量,frameSizeBytes 是一个 char[4] 数组。例如,当数组包含以下值(十六进制)

00 00 02 7b

frameSize 设置为 635,这是正确的值。此方法也适用于其他字节组合,但以下

除外
00 00 9e ba

对于这种情况,frameSize 设置为 4294967226,根据 this website,这是不正确的,因为它应该是 40634。为什么会发生这种行为?

您的 char 类型已在您的特定实现中签名,并通过大多数运算符进行整数提升。在使用有符号数组元素的地方使用强制转换为 unsigned char

编辑: 实际上正如 Olaf 在评论中指出的那样,您实际上应该更喜欢强制转换而不是 unsigned int(假设常见的 32 位 unsigned int)或 uint32_t 以避免 << 24 移位操作的潜在未定义行为。

为了保持整洁,我建议使用以下行的内联函数:

static inline uint32_t be_to_uint32(void const *ptr)
{
    unsigned char const *p = ptr;
    return p[0] * 0x1000000ul + p[1] * 0x10000 + p[2] * 0x100 + p[3];
}

注意:通过使用 unsigned long 常量,这段代码避免了 unsigned char 被提升为有符号 int 然后 multiplication/shift 导致整数溢出的问题(一个C) 恼人的历史特征。当然,您也可以按照 Olaf 的建议使用 ((uint32_t)p[0]) << 24