Reputation: 35992
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main()
{
string str("0");
vector<int> vec;
int upper_bound = str.size()-(3-vec.size());
int i = 0;
if ( i < upper_bound ) // Line 1
cout << "i < upper_bound - 1\n";
else
cout << "pass\n";
if ( i < (str.size()-(3-vec.size())) ) // Line 2
cout << "i < upper_bound - 2\n";
else
cout << "pass\n";
return 0;
}
Output is as follows:
pass
i < upper_bound
Question> Why Line 1 and Line 2 print different results?
Upvotes: 0
Views: 83
Reputation: 5387
While comparing signed and unsigned types, compiler will convert the signed types to unsigned. That creates the weird result.
Upvotes: 0
Reputation: 311078
The problem is that expression str.size()-(3-vec.size())) has some unsigned type. So it may not be negative. It is an unsigned type due to 1) str.size() and vec.size() are of some unsigned types according to definitions of std::string::size_type
and std::vector<int>::size_type
2) the usual arithmetic conversion.
In the first expression you explicitly assigned an unsigned expression to type int. So as the sign bit is set then the value of this object is negative.
To understand this try for example to execute these statements
std::cout << -1 << std::endl;
std::cout << -1u << std::endl;
or
std::cout << 0u -1 << std::endl;
Here -1u and 0u - 1 have type unsigned int and the same bit combination as -1.
Upvotes: 1
Reputation: 254661
Mathematically, str.size()-(3-vec.size())
is 1-(3-0)
, which is -2. However, since these are unsigned values, the result is also unsigned, and so has a large positive value.
Converting this to int
to initialise upper_bound
technically gives undefined behaviour, but in practise will give you -2; so the first test passes.
The second test compares with the large unsigned value rather than -2.
Upvotes: 8