user9284152
user9284152

Reputation: 113

C++ return statement not behaving as expected

I have the following C++ code:

return lineNum >= startLineNum
&& lineNum <= startLineNum + lines.size() - 1;

Here, lineNum is an int, startLineNum is an int, lines is a std::vector<std::string>, and lines.size() is of type size_t.

When lineNum is 2, startLineNum is 0, and lines.size() is 0, the code returns true even though false was expected. These values were the values displayed in the debugger.

Even after adding parentheses where possible:

return ((lineNum >= startLineNum)
&& (lineNum <= (startLineNum + lines.size() - 1)));

the code still incorrectly returns true.

When I refactor the code into this form:

int start = startLineNum;
int end = startLineNum + lines.size() - 1;
return lineNum >= start && lineNum <= end;

it now returns false as expected.

What is going on here? I have never come across this kind of strangeness before.

Upvotes: 4

Views: 256

Answers (2)

Bathsheba
Bathsheba

Reputation: 234635

lines.size() is more than likely an unsigned type. (If lines is a std::vector for example it's certainly unsigned.)

So due to the rules of argument promotion, and the fact that the terms in

startLineNum + lines.size() - 1;

are grouped from left to right, they are all converted to unsigned types.

This means that 0 + 0 - 1 is std::numeric_limits<decltype(lines.size())>::max() - a large number indeed, and lineNum is most likely less than it.

The rule of thumb: never use a negative when working with unsigned types, unless you really know what you're doing.

In your case, restate the problem to

lineNum < startLineNum + lines.size()

Upvotes: 11

Demosthenes
Demosthenes

Reputation: 1535

My guess would be that

lineNum <= startLineNum + lines.size() - 1;

is all unsigned types. linenum is 2, the other two are 0, and 0-1 in unsigned arithmetic is something VERY large (if 4 byte something above 4 billion).

Do instead

lineNum + 1 <= startLineNum + lines.size();

and all should be fine.

Upvotes: 1

Related Questions