【发布时间】:2020-01-27 21:32:04
【问题描述】:
好的,
我写了一个函数,它从一个十六进制文件中获取一个无符号字符,然后将它向左移动以适合一个 WORD、DWORD 或 QWORD,如下所示:
retVal |= ((unsigned char)(memory[i]) << (8 * j));
(在循环内,因此变量 i 和 j)。
现在视觉工作室提醒我可能的算术溢出。
我的问题:如果我将 j 限制为不超过 8(uint64_t 的大小),我可以安全地忽略此消息吗? 我总是对警告感到有些沮丧,并试图消除它们。
据我了解,在保存值之前向左移动多少并不重要,我弄错了吗?
编辑:
这是一个例子(这是我的功能):
int getValuePNTR(const char* memory, int &start, int size)
{
uint64_t retVal = 0;
//now just add up array fields
for (int i = start + size-1,j = size-1; j >= 0; --j, i--)
{
//fprintf(stdout, "\ncycle: %d, memory: [%x]", j, memory[i]);
if ((unsigned char)memory[i] == 00 && j > 0)
retVal <<= 8;
else
retVal |= ((unsigned char)(memory[i]) << (8 * j));
}
//get the next field after this one
start += size;
return retVal;
}
【问题讨论】:
-
对于
j等于8的情况,原来的第7位会占据什么位? -
您对您的编译器警告您左移操作而不是
|=操作符的信心有多大?或者,您对您的编译器没有警告您溢出的信心有多大,因为左侧仅提升为int,这可能只是一个 32 位值,而不是您的 64 位值重新假设? -
我无法重现警告。你能分享minimal reproducible example吗?您确定这一行是产生警告的行吗?
-
@SamVarshavchik 如您所见,我使用的是 uint64_t ,而不是普通的 DWORD
-
嗯,你写了那条评论答案已经贴出来了,清楚地解释了你对整数提升规则理解的错误。不,您在移位操作中没有使用 64 位值。
标签: c++ byte-shifting