SyntaxSage
SyntaxSage

Reputation: 357

CPP : arithmetic operation on empty vector size() output giving undefined behavior

My code

#include <stdio.h>
#include<bits/stdc++.h>
using namespace std;
int main()
{
    vector<int> nums;
    cout<<"size="<<nums.size()<<"\n";
    cout <<"diff1 = "<<0-2<<"\n";
    cout<<"diff2 = "<<nums.size()-2<<"\n";
    return 0;
}

Output

size=0
diff1 = -2
diff2 = 18446744073709551614

Expected output diff2 = -2 Not sure how this output is getting generated. I haven't seen this type of behavior.

Upvotes: 1

Views: 159

Answers (3)

Nilesh Solanki
Nilesh Solanki

Reputation: 356

 (nums.size()-2 ) will be unsigned why because nums.size() is unsigned.

and this will lead to below operator function of ostream

basic_ostream& operator<<( unsigned int value ); 

that's why you have unsigned result. if you want to see -2 then cast num.size() as int ((int)nums.size()-2) will result -2

more detail you can check https://en.cppreference.com/w/cpp/io/basic_ostream/operator_ltlt

Upvotes: 1

Bathsheba
Bathsheba

Reputation: 234785

No the behaviour is not undefined.

It's just that nums.size() is an unsigned type (formally a std::vector<int>::size_type), and the expression num.size() - 2 is evaluated in unsigned arithmetic due to the rules of implicit conversions. -1 in this case is std::numeric_limits<std::vector<int>::size_type>::max() and -2 is one less than that, which accounts for your output (264 - 2). This wrap-around behaviour of unsigned arithmetic is defined by the C++ standard.

As a rule of thumb, using negatives in unsigned arithmetic is best avoided.

Upvotes: 2

john
john

Reputation: 87932

nums.size() returns an unsigned type (actually size_t). Unsigned types have a smallest possible value of zero, so there's an issue when you try to generate a negative unsigned value. What the standard says is that the value wraps around. So a value of -1 converted to an unsigned type is the largest value that unsigned type can have, and similarly a value of -2 would be the second largest value that unsigned type can have.

That's what you are seeing in your output.

Upvotes: 4

Related Questions