简体   繁体   English

char []到uint32_t无法正常工作

[英]char[] to uint32_t not working properly

I am using the following to convert a char[4] to a uint32_t . 我正在使用以下内容将char[4]转换为uint32_t

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

frameSize is a uint32_t variable, and frameSizeBytes is a char[4] array. frameSize是一个uint32_t变量,而frameSizeBytes是一个char[4]数组。 When the array contains, for example, the following values (in hex) 例如,当数组包含以下值(十六进制)时

00 00 02 7b

frameSize is set to 635, which is the correct value. frameSize设置为635,这是正确的值。 This method also works for other combinations of bytes, with the exception of the following 此方法还适用于其他字节组合,但以下情况除外

00 00 9e ba

for this case, frameSize is set to 4294967226, which, according to this website , is incorrect, as it should be 40634 instead. 在这种情况下, frameSize设置为4294967226,根据此网站此值是不正确的,因为它应该是40634。 Why is this behavior happening? 为什么会发生这种现象?

Your char type is signed in your specific implementation and undergoes integer promotion with most operators. 您的char类型已在您的特定实现中签名,并且对大多数运算符进行整数提升。 Use a cast to unsigned char where the signed array elements are used. 在使用有unsigned char数组元素的地方使用强制转换为unsigned char

EDIT: actually as pointed out by Olaf in the comment, you should actually prefer casts to unsigned int (assuming common 32-bit unsigned int ) or uint32_t to avoid potential undefined behavior with the << 24 shift operation. 编辑:实际上,正如Olaf在评论中指出的那样,您实际上应该更喜欢对unsigned int (假定为普通的32位unsigned int )或uint32_t进行强制转换,以避免<< 24 shift操作可能出现的不确定行为。

To keep things tidy I'd suggest an inline function along the lines of: 为了使事情保持整洁,我建议使用以下内联函数:

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];
}

Note: by using an unsigned long constant this code avoids the problem of unsigned char being promoted to signed int and then having the multiplication/shift cause integer overflow (an annoying historical feature of C). 注意:通过使用unsigned long常量,此代码避免了将unsigned char提升为有符号int ,然后使乘法/移位引起整数溢出(C的令人讨厌的历史特征)的问题。 Of course you could also use ((uint32_t)p[0]) << 24 as suggested by Olaf. 当然,您也可以使用((uint32_t)p[0]) << 24如Olaf所建议。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM