Is it possible to use negative integers with size_t?

I just saw some C ++ code. He used the condition to decide whether to go forward or backward through std::vector . The compiler does not complain, but I thought size_t is unsigned. This is dangerous?

 vector<int> v { 1,2,3,4,5 }; bool rev = true; size_t start, end, di; if (rev) { start = v.size()-1; end = -1; di = -1; } else { start = 0; end = v.size(); di = 1; } for (auto i=start; i!=end; i+=di) { cout << v[i] << endl; } 
+5
source share
4 answers

It is well-defined for using unsigned integers (and unsigned size_t ) in this way with wraparound: this behavior is guaranteed by the standard, and not with familiar integers where it is not guaranteed by the standard.

However, it is useless.

Typically, to avoid problems due to implicit unsigned ad campaigns, use unsigned integers for bit level data, use unsigned integers for numbers. Where you need a signed integer corresponding to size_t there ptrdiff_t for you. Define a function n_items with a signed result, for example

 using Size = ptrdiff_t; template< class Container > auto n_items( Container const& c ) -> Size { return end( c ) - begin( c ); } 

and you are set to work, no more stupid supporters of the compiler.


Instead of too smart given code

 vector<int> v { 1,2,3,4,5 }; bool rev = true; size_t start, end, di; if (rev) { start = v.size()-1; end = -1; di = -1; } else { start = 0; end = v.size(); di = 1; } for (auto i=start; i!=end; i+=di) { cout << v[i] << endl; 

execute for example

 const vector<int> v { 1,2,3,4,5 }; const bool reverse = true; // whatever for( int i = 0; i < n_items( v ); ++i ) { const int j = (reverse? n_items( v ) - i - 1 : i); cout << v[j] << endl; } 
+6
source

I can't talk about how secure this code is, but I think this is a pretty bad style. A better way would be to use iterators that support forward or reverse iteration.

For instance:

 std::vector<int> v = { 1, 2, 3, 4, 5 }; bool rev = true; if (rev) { for (auto itr = v.rbegin(); itr != v.rend(); ++itr) { std::cout << *itr << "\n"; } } else { for (auto itr = v.begin(); itr != v.end(); ++itr) { std::cout << *itr << "\n"; } } 
+1
source

Is it possible to use negative integers with size_t?

No, this is dangerous. Overflow.

 size_t a = -1; std::cout << a << "\n"; 

Conclusion:

 4294967295 // depends on the system, largest value possible here 
0
source

When I need to deal with signed types, I always use:

 typedef std::make_signed<std::size_t>::type ssize_t; // Since C++11 

... as a signed alternative to std :: size_t.

I appreciate this question for several years, but I hope this helps others. Confirm moodycamel :: ConcurrentQueue .

0
source

Source: https://habr.com/ru/post/1212314/


All Articles