Am 22.01.2012, 13:49 Uhr, schrieb Jonathan M Davis <jmdavisp...@gmx.com>:
Down with tabs! ;)
One issue with unsigned integers right off the bat is for loops.
for(size_t i = a.length; i > 0; --i) {}
is not going to work.
That is C style. In D you would write: foreach_reverse(i; 0 .. a.length)
{}, which is safe and corrects the two bugs in your code.
Another potentially nasty situation is subtraction. It
can do fun things when you subtract one unsigned type from another if
you're
not careful (since if the result is negative and is then assigned to an
unsigned integer...). There are probably others, but that's what comes
to mind
immediately. In general, it comes down to issues with them rolling over
and
becoming incredibly large values when they go below 0.
I'm always careful when subtracting unsigned ints for the simple reason
that the code working on them would be incorrect if results were negative.
One example is subtracting two TickDurations. You always know which one is
the lower. The same goes for offsets into files. When you copy the block
between two locations you cannot exchange start and end. Imagine we had
checked integers now, a proposal that doesn't seem far fetched. Would they
scream in pain if I wrote "checked_ulong duration = start_time -
end_time"? Yes.
Sure, unsigned types can be useful, and if you're careful with them, you
can
be fine, but there are definitely cases where they cause trouble. Hence,
why
many programmers argue for not using them unless you actually need them.
- Jonathan M Davis
I guess my mental model of integers has grown on the idea that an unsigned
integer matches the addressable memory of my computer, and thus it is the
natural choice there for array lengths and whatever is limited only by
available RAM and comes in positive counts; whereas I 'waste' half the
range and have only 'half' a match with signed types.
I will put this under "tabs vs. spaces". :)