lmi
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [lmi] Avoiding unsigned


From: Vadim Zeitlin
Subject: Re: [lmi] Avoiding unsigned
Date: Tue, 12 Jun 2018 15:47:30 +0200

On Mon, 11 Jun 2018 23:43:12 +0000 Greg Chicares <address@hidden> wrote:

GC> On 2016-03-27 21:24, Vadim Zeitlin wrote:
GC> [...]
GC> > <digression-on-the-use-of-unsigned-you-should-feel-free-to-skip>

 FWIW my thinking has evolved since this written 2 years ago. I've now
resigned to using int because the problems with size_t/unsigned just seem
to be insurmountable. So I don't have any objections to the recent changes
in lmi.


 I'd just like to address a few small points:

GC> In that panel discussion, Stroustrup continues:
GC> 
GC> /// Now, when people use unsigned numbers, they usually have a reason,
GC> /// and the reason will be something like, well, 'it can't be negative',
GC> /// or 'I need an extra bit'. If you need an extra bit, I am very
GC> /// reluctant to believe you that you really need it, and I don't think
GC> /// that's a good reason.

 This is a straw man argument if I've ever seen one. Nobody uses unsigned
to just have an extra bit since many (~30?) years. And "it can't be
negative" belittles the importance of this reason: it's not just that it
"can't be", but that using unsigned type shows it clearly to the user of
the API and, at least as importantly, conversely, not using unsigned
indicates that the value _can_ be negative. E.g. in wxWidgets,
GetSelection() returns int because it can return either (unsigned) index or
wxNOT_FOUND, while GetCount() returns unsigned because it can never fail.

 Of course, nowadays I'd write GetSelection() as returning optional<int>
and GetCount() as returning int, which is, arguably, even better. But I
remain convinced that the API design above was more sound than returning
int from both functions.


GC> >  So, on balance, I only see one tiny argument not to use unsigned. OTOH
GC> > there are two big arguments in favour of using it, of very different
GC> > varieties:
GC> > 
GC> > 1. Theoretic one: it provides more semantic information which is always
GC> >    a good thing. It also reduces cognitive dissonance which happens when
GC> >    something that obviously can't be negative is represented by a signed
GC> >    type. Again, for me this is pretty similar to representing an integer
GC> >    by a double: sure, it can be done, but this seems to be obviously 
wrong.
GC> 
GC> Okay, then, how about using something like one of the following?
GC>   using count_t = int;
GC>   using index_t = int;
GC>   using nonneg_int = int;
GC> where, instead of 'int', we could use this (as in 'ssize_lmi.hpp'):
GC>   using ssize_t = std::make_signed_t<std::size_t>;
GC> or Herb Sutter's recommendation:
GC>   https://github.com/isocpp/CppCoreGuidelines/pull/1115
GC>   namespace gsl { using index = ptrdiff_t; }
GC> That would provide the same semantic suggestion as 'unsigned',
GC> while avoiding mixed-mode arithmetic.

 Yes, I think it's a good idea. But I also think it's an even better idea
to use wrapper types that should not be convertible to each other, e.g. I'd
prefer to use a census_column_index_t instead of just index_t for the index
of columns in CensusView control.

GC> > 2. Practical one: unsigned type (size_t) is used everywhere in the 
standard
GC> >    library and if the rest of the code uses signed types, it requires
GC> >    converting, implicitly (dangerous; results in warnings) or explicitly
GC> >    (annoying; can still be dangerous) back and forth between them.
GC> 
GC> We can attack that problem at the source.

 Yes, I like what you've done with ssize() and am probably going to steal
it for my own code in the future. Thanks for doing this!

GC> By minimizing our use of unsigned types (except for bit manipulations),
GC> we choke off the potential for mixed-arithmetic surprises.

 This is definitely a big win. But note that with wrapper types we can
forbid all operations that don't make sense for indices completely (and
often enough no operations need to be allowed on them at all).

 Thanks once again for cleaning this up!
VZ


reply via email to

[Prev in Thread] Current Thread [Next in Thread]