我只想将uint8_t数组连接到uint64_t。事实上,我解决了我的问题,但需要了解原因。这是我的代码;
uint8_t byte_array[5];
byte_array[0] = 0x41;
byte_array[1] = 0x42;
byte_array[2] = 0x43;
byte_array[3] = 0x44;
byte_array[4] = 0x45;
cout << "index 0: " << byte_array[0] << " index 1: " << byte_array[1] << " index 2: " << byte_array[2] << " index 3: " << byte_array[3] << " index 4: " << byte_array[4] << endl;
/* This does not work */
uint64_t reverse_of_value = (byte_array[0] & 0xff) | ((byte_array[1] & 0xff) << 8) | ((byte_array[2] & 0xff) << 16) | ((byte_array[3] & 0xff) << 24) | ((byte_array[4] & 0xff) << 32);
cout << reverse_of_value << endl;
/* this works fine */
reverse_of_value = (uint64_t)(byte_array[0] & 0xff) | ((uint64_t)(byte_array[1] & 0xff) << 8) | ((uint64_t)(byte_array[2] & 0xff) << 16) | ((uint64_t)(byte_array[3] & 0xff) << 24) | ((uint64_t)(byte_array[4] & 0xff) << 32);
cout << reverse_of_value << endl;
第一个输出为“44434245”,第二个输出为“4544434241”,这就是我想要的。
因此,正如我们所看到的,当我使用每个字节转换为uint64_t代码时,如果我不使用强制转换它会给我无关的结果。任何人都能解释一下原因吗?
答案 0 :(得分:6)
左移uint8_t
,许多位不一定会起作用。左侧操作数将被提升为int
,其宽度您不知道。 可以已经是64位,但它可能是32位甚至是16位,在这种情况下......结果会在哪里?它没有足够的空间!您的代码稍后将结果放入uint64_t
并不重要:表达式是单独评估的。
您已在第二个版本中正确修复了此问题,在之前转换为uint64_t
左移。在这种情况下,表达式肯定会有所期望的行为。
答案 1 :(得分:2)
这是一个示例,显示左移将char转为0.至少它在我的机器上执行,gcc 4.8.4,Ubuntu 14.04 LTS,x86_64。
#include <iostream>
using std::cout;
int main()
{
unsigned char ch;
ch = 0xFF;
cout << "Char before shift: " << static_cast<int>(ch) << '\n';
ch <<= 10;
cout << "Char after shift: " << static_cast<int>(ch) << '\n';
}
另请注意我对上述原始问题的评论,在某些平台上,0x45移位32位实际上最终位于64位值的最低有效字节中。
答案 2 :(得分:2)
在C ++中,将类型移位超过类型中的位数是未定义的行为。有关详细信息,请参阅此答案:https://stackoverflow.com/a/7401981/1689844