我有以下C ++代码:
return lineNum >= startLineNum
&& lineNum <= startLineNum + lines.size() - 1;
此处lineNum
为int
,startLineNum
为int
,lines
为std::vector<std::string>
,lines.size()
属于size_t
类型。
当lineNum
为2时,startLineNum
为0,lines.size()
为0时,即使预计true
,代码也会返回false
。这些值是调试器中显示的值。
即使在可能的情况下添加括号:
return ((lineNum >= startLineNum)
&& (lineNum <= (startLineNum + lines.size() - 1)));
代码仍然错误地返回true
。
当我将代码重构为这种形式时:
int start = startLineNum;
int end = startLineNum + lines.size() - 1;
return lineNum >= start && lineNum <= end;
现在按预期返回false
。
这里发生了什么?我以前从未遇到过这种陌生感。
答案 0 :(得分:11)
lines.size()
很可能是无符号类型。 (如果lines
是std::vector
,例如它当然 unsigned
。)
因此,由于参数提升的规则,以及
中的条款这一事实startLineNum + lines.size() - 1;
从左到右分组,它们都转换为unsigned
类型。
这意味着0 + 0 - 1
是std::numeric_limits<decltype(lines.size())>::max()
- 确实是一个很大的数字,lineNum
很可能比它少。
经验法则:在使用未签名类型时,绝不要使用否定词,除非您真的知道自己在做什么。
在您的情况下,请将问题重新提交到
lineNum < startLineNum + lines.size()
答案 1 :(得分:1)
我猜是
lineNum <= startLineNum + lines.size() - 1;
是所有无符号类型。 linenum
为2,其他两个为0,无符号算术中的0-1非常大(如果4字节超过40亿)。
改为
lineNum + 1 <= startLineNum + lines.size();
一切都应该没问题。