Why don't compilers do safe signless and signed matching?

As we know, such code generates a warning:

for (int i = 0; i < v.size(); ++i)

The solution is something like auto i = 0u;, decltype(v.size())or std::vector<int>::size_type, but pretend that we are forced to have both a signed and an unsigned value. The compiler will automatically add intto unsigned int(the actual type does not matter). Using an explicit cast static_cast<unsigned int>(i)causes the warning to go away, but this is bad because it did the same thing the compiler did and silenced the important warning!

The best solution:

if ((i < 0) || (static_cast<unsigned int>(i) < v.size()))

It is clear that C is “closer to metal” and, as a result, is more dangerous. But in C ++ there is no excuse for this. Because C ++ and C diverge (as they have done over the years), hundreds of C ++ enhancements have enhanced security. I very much doubt that such a change could hurt performance.

Is there a reason why compilers do not do this automatically?

NB : this happens in the real world. See VU # 159523 Vulnerability Note :

Adobe Flash - , Flash calloc(). . calloc() size_t, , , , calloc() NULL, , .

+4
2

++ , , , sign/unsigned . . Stroustrups ++ 1986 .

, .

, ++ 11 , ranged-for auto:

for (auto i : v)
+1

++ . : string("hello").size() < -5" , ; . , , , , , , , , , ; , .

, , , unsigned. , ++ , , , . unsigned ++, , , Java-.

, , , .

, , size , . ptrdiff_t, , int.

- n_items :

using Size = ptrdiff_t;

template< class Container >
auto n_items( Container& c )
    -> Size
{ return c.size(); }

, , std::list , end(c) - begin(c). (1). :

template< class Item, Size n >
auto n_items( Item (&)[n] )
    -> Size
{ return n; }

: , .


1) , , . . I.e, , , , .

+1

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


All Articles