The following code
#include <vector>
#include <iostream>
using namespace std;
int main() {
vector<int> value;
cout << value.size() << endl; // output 0
cout << value.size() - 1 << endl; // output 18446744073709551615
}
Why the second output is not -1? What happens at the second cout?
vector::size()
is of type size_t
which is an unsigned type, and unsigned integers can't represent negative numbers.
Unsigned integer types in C++ do “wrap around arithmetic” a.k.a. clock arithmetic a.k.a. modulo arithmetic. And the result of any standard library size
function is unsigned, usually the type size_t
. And so, when you subtract 1 from 0 of type size_t
, you get the largest size_t
value.
To avoid these problems you can include <stddef.h>
and define
using Size = ptrdiff_t;
and further (the second function here requires inclusion of <bitset
),
template< class Type >
auto n_items( Type const& o )
-> Size
{ return o.size(); }
template< Size n >
auto n_items( std::bitset<n> const& o )
-> Size
{ return o.count(); } // Corresponds to std::set<int>::size()
Then you can write
n_items( v )
and get a signed integer result, and -1
when you subtract 1 from 0.
The output is automatically casted to size_t
because that's the return type of value.size()
, which is an unsigned
type. Hence you see an unsigned
value printed.
The .size() returns a 'size_t' type that is a unsigned int. The second output is the maximum integer of your machine.
value.size() returns an unsigned type, so by doing -1 you are actually doing an overflow