Am Sat, 22 Nov 2014 06:34:11 +1100 schrieb "Daniel Murphy" <[email protected]>:
> "Andrei Alexandrescu" wrote in message > news:[email protected]... > > > What is your point? (Honest question.) > > That using signed integers exclusively eliminates one class of bugs, while > making another class only marginally more likely. > > > Are you proposing that we make all array lengths signed? > > No, I think that ship has sailed. But I recommend avoiding unsigned types > for general arithmetic. I think it is more about getting into the right mind set. All hardware integer types are limited and need overflow checking. As someone using unsigned types all the time, all I need to keep in mind are two rules: 1) Overflow: uint number; … number = 10 * number + ch - '0'; It is handled with: if (number > uint.max / 10) if (number > uint.max - (ch - '0')) An underflow practically doesn't happen with unsigned arithmetic. 2) Subtraction Order Subtract the smaller value from the bigger one. a) Commonly one entity is of greater magnitude than the other: fileSize - offset length - idx b) If both entities are equal before the Lord I make them ordered to make rule 1) hold: if (fileSize1 > fileSize2) { // Do one thing } else { // Do the other thing } The length of an array is perfectly represented by a size_t. My goal is to do the technically correct thing and thereby make overflow bugs impossible. I.e. With unsigned types in general and size_t in particular you cannot pass anything that is prone to underflow/overflow. It is all natural numbers and any overflows must have happened already before the array got indexed. Inside opIndex, the unsigned types simplify the range checks (by the compiler or explicit) by removing the need to test for < 0. At the end of the day I find myself using unsigned types much more frequently than signed types because I find it easier to keep them in check and reason about. -- Marco
