9

Whats the rationale for using signed numbers as indexes in .Net?

In Python, you can index from the end of an array by sending negative numbers, but this is not the case in .Net. It's not easy for .Net to add such a feature later as it could break other code perhaps using special rules (yeah, a bad idea, but I guess it happens) on indexing.

Not that I have ever have needed to index arrays over 2,147,483,647 in size, but I really cannot understand why they choose signed numbers.

Can it be because it's more normal to use signed numbers in code?

Edit: I just found these links:

The perils of unsigned iteration in C/C++

Signed word lengths and indexes

Edit2: Ok, a couple of other good reasons from the thread Matthew Flaschen posted:

  • Historical reasons as it's a c-like language
  • Interop with c
simendsjo
  • 4,739
  • 2
  • 25
  • 53
  • 1
    See [Why is Array.Length an int, and not an uint](http://stackoverflow.com/questions/6301/why-is-array-length-an-int-and-not-an-uint). – Matthew Flaschen Jun 17 '10 at 08:42
  • possible duplicate of [Why does .NET use int instead of uint in certain classes?](http://stackoverflow.com/questions/782629/why-does-net-use-int-instead-of-uint-in-certain-classes) – nawfal Jul 15 '14 at 15:39

4 Answers4

5

It may be to the long tradition of using a value below 0 as an invalid index. Methods like String.IndexOf return -1 if the element is not found. Therefore, the return value must be signed. If index-consumers would require unsigned values, you would have to a) check and b) cast the value to use it. With signed indices, you just need the check.

Arne
  • 750
  • 5
  • 10
  • Seems plausible, but that's the only example I can think of. Using a negative number as an index is a runtime error. IndexOf could have been implemented another way. – simendsjo Jun 17 '10 at 08:44
  • Another example is [List.BinarySearch](http://msdn.microsoft.com/en-us/library/w4e7fxsh.aspx) where the return is "The zero-based index of item in the sorted List, if item is found; otherwise, a negative number that is the bitwise complement of the index of the next element that is larger than item or, if there is no larger element, the bitwise complement of Count." – Robert Paulson Jun 27 '10 at 20:20
3

For simplicity of course. Do you like trouble doing size arithmetic with unsigned ints?

Rotsor
  • 13,655
  • 6
  • 43
  • 57
  • The example you posted represents a perfect example of an ill-programming practice. If somebody is such an amateur coder, not even signed integers will save him from buffer under/overruns. – Simon Rozman Jun 14 '17 at 08:11
2

Unsigned isn't CLS compliant.

Hans Olsson
  • 54,199
  • 15
  • 94
  • 116
  • But Microsoft made the CLS specs right? They had the final say in this case and they did choose to use signed numbers. – Blindy Jun 17 '10 at 08:34
  • 1
    @Blindy: I think they wanted to make the CLS specs as inclusive as possible, and not all languages support unsigned numbers (for example VB6 and even if VB6 isn't a CLS language I suppose they might have wanted to increase the chance of interoperability). – Hans Olsson Jun 17 '10 at 09:11
  • @Blindy: Java doesn't even have unsigned. – kizzx2 Apr 27 '11 at 05:53
0

The primary usefulness of unsigned numbers arises when composing larger numbers from smaller ones and vice versa. For example, if one receives four unsigned bytes from a connection and wishes to regard their value, taken as a whole, as a 32-bit integer, using unsigned types means one can simply say:

  value = byte0 | (byte1*256) | (byte2*65536) | (byte3*16777216);

By contrast, if the bytes were signed, an expression like the above would be more complicated.

I'm not sure I really see any reason for a language designed nowadays not to include unsigned versions of all types shorter than the longest signed integer type, with the semantics that all integer (meaning discrete-quantity-numerics, rather than any particular type) operations which will fit entirely within the largest signed type will by default be performed as though they were operating upon that type. Including an unsigned version of the largest signed type would complicate the language specification (since one would have to specify which operations must fit within range of the signed type, and which operations must fit within range of the unsigned type), but otherwise there should be no problem designing a language so that if (unsigned1 - unsigned2 > unsigned3) would yield a "numerically-correct" result even when unsigned2 is greater than unsigned1 [if one wants unsigned wraparound, one would explicitly specify if ((Uint32)(unsigned1 - unsigned2) > unsigned3)]. A language which specified such behavior would certainly be a big improvement over the mess that exist in C (justifiable, given its history), C#, or vb.net.

supercat
  • 77,689
  • 9
  • 166
  • 211