q0987
q0987

Reputation: 35992

why `( i < (str.size()-(3-vec.size())) )` is true?

#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

Answers (3)

Nipun Talukdar
Nipun Talukdar

Reputation: 5387

While comparing signed and unsigned types, compiler will convert the signed types to unsigned. That creates the weird result.

Upvotes: 0

Vlad from Moscow
Vlad from Moscow

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

Mike Seymour
Mike Seymour

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

Related Questions