You are a stupid programmer, you can't have that

IGotD- nise at nise.com
Sat Aug 7 17:20:09 UTC 2021


On Saturday, 7 August 2021 at 14:21:52 UTC, Guillaume Piolat 
wrote:
>
> It's hard to appreciate how good that Java decision was without 
> maintaining large C++ codebases.
> Unsigned/signed math and the implicit conversions between them 
> absolutely DO cause bugs in real-world code, the most prominent 
> of which must be:
>
>     #include <vector>
>     #include <iostream>
>
>     bool isArrayOrdered(std::vector<int>& vec)
>     {
>         for (size_t n = 0; n < vec.size() - 1; ++n)
>         {
>             if (vec[n] > vec[n+1])
>                 return false;
>         }
>         return true;
>     }
>
>     int main(int argc, char** argv)
>     {
>         std::vector<int> v;
>         // works if the array isn't empty
>         // v.push_back(4);
>         std::cout << isArrayOrdered(v);
>     }
>
>
> See the bug in isArrayOrdered?
>
> It will fail with an empty array since:
> 1. vec.size() yields size_t
> 2. vec.size() - 1 stays unsigned, if the size was zero it is 
> now the maximum possible size
> 3. and we have an unsigned comparison, with a very long loop 
> which in this case will cause out of bounds
>
> (Solution: use + 1 on the other side of the comparison)
>
> Similar problems happen when people store image size with 
> unsigned, or widget positions in unsigned, or dates in unsigned 
> integers.
>
> All of these problems disappear:
> - if only signed integers are available.
> - if container length return a signed integer (and that's what 
> D could have done...)
> - if comparison or arithmetic with mixed signedness is 
> forbidden (but: lots of casts)
>
> Programmers do not actually learn about integer promotion 
> except when forced by such bugs.
> It has nothing to with programmers being dumb or low-skilled, 
> and everything to do with an economy of information: it's 
> better if the problem doesn't exist in the first place.
>
> So I believe Java made a decision that saves up mental space.


Your example is a valid argument as well as you provide the 
solution for unsigned math. The most interesting with the example 
is that your example provide a one comparison solution for 
signed/unsigned. This type of error would quickly be found as it 
would generate an exception in both C++ and D. Then perhaps the 
lazy programmer would just do an extra check when the size is 
zero. For example

      bool isArrayOrdered(std::vector<int>& vec)
      {
          if (vec.empty())
          {
               return true;
          }

          for (size_t n = 0; n < vec.size() - 1; ++n)
          {
              if (vec[n] > vec[n+1])
                  return false;
          }
          return true;
      }


This would be better but requires an extra check, two 
comparisons. I think you provide an excellent example that the 
problem isn't signed/unsigned math but how you can use the 
arithmetics to your advantage regardless signed/unsigned. There 
are often solutions when using unsigned math and that is what I 
think the programmer should learn instead of limiting the 
language.



More information about the Digitalmars-d mailing list