【发布时间】:2017-04-05 03:11:37
【问题描述】:
我正在为 Win64 上的 32 位程序编写 DLL 插件,在 Visual Studio 2015 中编译为 Win32/Debug。我需要将 unsigned char(上游定义)左移 56 位到 UINT64 中,以便 0xFF应该变成 0xFF000000000000。
实际发生的情况是,对于任何大于 32 的移位值,结果是 (shift - 32) 位的移位,我的目标 UINT64 的高 32 位变为全 1,因此:
int NmeaPgn::sf_get_bytes(TCanMessage *m, UINT8 start_byte, UINT8 bytes)
{
UINT64 r = 0; /* Could need to fetch up to 8 bytes, as in 60928 */
INT8 i;
for (i = start_byte + bytes - 1; i >= start_byte; --i)
{
r |= (m->data[i] << 8 * (i - start_byte));
}
...
}
使用 VS 调试器,我看到:
m->data[i] == 0xC0
i == 0x7
start_byte == 0
bytes == 8 (so that shift == 8 * (7 - 0) == 56)
then:
r == 0xFFFFFFFFc0000000
我已阅读:
https://msdn.microsoft.com/en-us/library/336xbhcz.aspx
Left shift an integer by 32 bits
我能看到的最接近答案的是 Andrey Nasonov 对后者的回答 (https://stackoverflow.com/a/33058550/7817631),但我使用的是 64 位机器(Core i5 上的 Win7-64),所以我不希望这是直接相关。
【问题讨论】:
-
可能
m->data[i]是一个 32 位值(或更小)。顺便说一句,您不应该将解决方案编辑到问题中,而是可以发布答案。 (尽管回答您自己的问题可能有最低代表要求,IDK)。 -
请不要发布有问题的答案。你可以answer你自己的问题。
-
@MartinZhai 根据该链接需要 15 个代表,所以我猜在这种情况下 OP 不走运
-
如果调试器说
m->data[i]是0xC0那么它可能是一个字节(8 位数量) - 根据标准提升规则提升为int。int在你的编译器上是 32 位......你得到一个 32 位移位。事实上,你可以合法地得到从time travel 到程序终止的任何结果,因为在 C++ 中未定义大于被移位整数值大小的移位结果 - here's an answer to that effect。 -
顺便说一句,如果您将示例缩减为 minimal reproducible example - 一种非常有用的发现技术,您本可以自己解决这个问题。
标签: c++ visual-studio visual-c++ bit-manipulation