C++ 为什么将值移到大于其大小的位置不会导致0?
实际精炼问题: 为什么不打印0C++ 为什么将值移到大于其大小的位置不会导致0?,c++,arrays,visual-c++,C++,Arrays,Visual C++,实际精炼问题: 为什么不打印0 #include "stdafx.h" #include <iostream> #include <string> int _tmain(int argc, _TCHAR* argv[]) { unsigned char barray[] = {1,2,3,4,5,6,7,8,9}; unsigned long weirdValue = barray[3] << 32; std::cout <&
#include "stdafx.h"
#include <iostream>
#include <string>
int _tmain(int argc, _TCHAR* argv[])
{
unsigned char barray[] = {1,2,3,4,5,6,7,8,9};
unsigned long weirdValue = barray[3] << 32;
std::cout << weirdValue; // prints 4
std::string bla;
std::getline(std::cin, bla);
return 0;
}
因此,反汇编很好。移位计数被屏蔽为5位,这将范围限制为0-31 因此,32的移位与零的移位相同
代码实际上是不正确的。除非通过
char
数组显式执行,否则无法执行此操作。使用中间ulValue
会将代码转化为非法行为,在技术上是未定义的行为。而且,由于long
和float
之间的endianness和可能的大小差异,它不会在所有平台上都工作。您对它的实际工作有多大把握?在现实世界中运行时,USNBytes的数量是否会超过3?目前,该代码无法用于usIndex>3I,我想知道它为什么在这里工作。我知道有更好的解决方案,我只是想知道为什么这一方法在过去的十年里奏效。是的,我有一个例子,usNumberOfBytes是28,一种可能的工作方式,正确的方法可能是这样做,例如float fValue=*(float*)&m_oData.pabyDataBytes[usIndex]
,然后用sizeof(float)
增加usIndex
。那么你真正想问的是移位操作,以及它为什么“有效”?也许您可以稍微澄清一下,删除不相关的代码?最好创建一个?实际上,它不应该起作用。如果sizeof(unsigned long)==4
,则当usIndex>3
时,它将移位到许多位,并导致未定义的行为。
10: unsigned long weirdValue = barray[3] << 32;
00411424 movzx eax,byte ptr [ebp-1Dh]
00411428 shl eax,20h
0041142B mov dword ptr [ebp-2Ch],eax
unsigned long ulValue = 0;
for (USHORT usIndex = 0; usIndex < m_oData.usNumberOfBytes; usIndex++)
{
if (usIndex > 0 && (usIndex % 4) == 0)
{
float* pfValue = (float*)&ulValue;
oValues.push_back(*pfValue);
ulValue = 0;
}
ulValue += (m_oData.pabyDataBytes[usIndex] << (8*usIndex)); // Why does this work for usIndex > 3??
}
ulValue += (m_oData.pabyDataBytes[usIndex] << (8*(usIndex%4)))
13D61D0A shl ecx,3 // multiply uIndex by 8
13D61D0D shl eax,cl // shift to left, does nothing for multiples of 32
13D61D0F add eax,dword ptr [ulValue]
13D61D15 mov dword ptr [ulValue],eax