Juha Nieminen wrote:
> I was once taught that if some integral value can never have negative
> values, it's a good style to use an 'unsigned' type for that: It's
> informative, self-documenting, and you are not wasting half of the value
> range for values which you will never be using.
>
> I agreed with this, and started to always use 'unsigned' whenever
> negative values wouldn't make any sense. I did this for years.
>
> However, I slowly changed my mind: Doing this often causes more
> problems than it's worth. A good example:
>
> If you have an image class, its width and height properties can
> *never* get negative values. They will always be positive. So it makes
> sense to use 'unsigned' for the width and height, doesn't it? What
> problems could that ever create?
>
> Well, assume that you are drawing images on screen, by pixel
> coordinates, and these images can be partially (or completely) outside
> the screen. For example, the left edge coordinate of the image to be
> drawn might have a negative x value (for example drawing a 100x100 image
> at coordinates <-20, 50>). Since the coordinates are signed and the
> dimensions of the image are unsigned, this may cause signed-unsigned
> mixup. For example this:
>
> if(x - width/2 < 1) ...
>
> where 'x' is a signed integer, gives *different* results depending on
> whether 'width' is signed or unsigned, with certain values of those
> variables (for example x=2 and width=10). The intention is to treat
> 'width' here as a signed value, but if it isn't, the comparison will
> malfunction (without explicitly casting 'width' to a signed value). This
> may well go completely unnoticed because compilers might not even give
> any warning (for example gcc doesn't).
>
> Thus at some point I started to *always* use signed integers unless
> there was a very good reason not to. (Of course this sometimes causes
> small annoyances because STL containers return an unsigned value for
> their size() functions, but that's usually not a big problem.)
>
> It would be interesting to hear other opinions on this subject.
Yes, I have had similar experiences / thoughts.
Some while back I thought it would be a good idea to use unsigned integers.
I don't think I read anywhere that this is good practice, and as a spare
time programmer I have never been on a C++ course; it just seemed 'obvious'
that using unsigned for values that can never be negative would be safer.
So I tried using unsigned integers in my simulation project. However I soon
started finding that I was getting compiler warnings about unsigned /
signed conversions. When I started trying to change more variables to
unsigned to stop the warnings, I just started getting more warnings.
I pretty soon abandoned the whole thing on the basis that it was more
trouble than it was worth (but also feeing slightly guilty).
I supposed that part of the problem might have been that I was trying to
retro-fit existing code, rather than coding from the outset to use
unsigned. However, the example given by Juha above makes me think that this
is not just a problem of retro-fitting. There seem to be scenarios where
using unsigned int is positively dangerous, particularly in scenarios where
the compiler doesn't generate a warning (and I've just confirmed on my own
gcc setup that there are such scenarios).
Rather than using unsigned, I use Assertions liberally, and having seen the
danger of signed/unsigned conversions, I think this is the right approach.
Chris Gordon-Smith
www.simsoup.info