Discussion:
[go-nuts] Why len(*Type) return int not uint ?
zuxiong lin
2014-12-24 03:58:28 UTC
Permalink
I am Curious about the Title Question.
--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Dave Cheney
2014-12-24 04:01:32 UTC
Permalink
Because it would make a for loop very inconvenient to type

for i := 0; i < len(something); i++ {
// something
}

Would not complie.

The very wise Alan Donovan said recently, use signed types for everything except bit manipulation.
--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Dmitri Shuralyov
2014-12-24 05:26:21 UTC
Permalink
It would also be hard to do a reverse loop:

for i := len(something) - 1; i >= 0; i-- {
// ...
}

Would be an infinite loop if i is unsigned.

That demonstrates the following observation. While values of len are always
non-negative, the operations that are done with output of len may sometimes
result in negative numbers. You don't want to limit yourself from being
able to use -1, etc.
Post by Dave Cheney
Because it would make a for loop very inconvenient to type
for i := 0; i < len(something); i++ {
// something
}
Would not complie.
The very wise Alan Donovan said recently, use signed types for everything
except bit manipulation.
--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
minux
2014-12-25 03:51:44 UTC
Permalink
Post by zuxiong lin
I am Curious about the Title Question.
This has been asked again and again.

Search the archive for more detailed explanations.

The short answer is:
Basically, due to the way Go's type system works, we need to use the same
type of
integer for both index and length.

Both kind of the integer type (unsigned and signed) have their own subtle
points where
changing 1 in the binary representation will change a lot in the number it
actually represents.

For signed numbers, the point is at largest integer. for example, adding
one to the largest
positive integer will make it the smallest negative integer.

For unsigned numbers, the point is at zero. Subtracting one from zero will
make the largest
unsigned number.

We want to chose one type of integer where most of the operations will not
come near those
subtle points.

For length/index of an object, it's easy for it to be close to zero, so
using unsigned means
we're pretty near the subtlety, a off-by-one error might make your program
crash by trying to
allocate all the memory in your machine or make your loop endless, whereas
it's hard for the
length/index to reach the largest representable positive number (the
runtime allocation routine
will panic before you even come close to that due to out-of-memory
situations).

Even though it might seem that using unsigned integer to represent length
is the most
natural thing to do, using unsigned integer to represent index is not
something you'd like.
Others have already provided examples for that.

Some might argue that using signed integer loses half of the numbers. But
that is unlikely
to matter much.

On 64-bit systems, have you seen 2^64 bytes of memory? In fact, most
current cpus only
implements 48-bit of the physical memory space.

On 32-bit systems, it's true that you can't have a byte slice or array
larger than 2G, but
as soon as your increase the size of the element to more than 1 byte, 2G
elements will
be more than enough to hit the address space limitation of 32-bit systems.
(Not to mention that on real 32-bit systems, user space programs typically
only have
~3GB of address space available, and to manage 3GB heap, Go's current
runtime will
need 384MB of bitmap, and if we include other memory overheads, it's
impossible for
a 32-bit Go programs to have close to 2GB of usable memory on a real 32-bit
machine.
(By real 32-bit machine, I mean those that are using 32-bit only
processors, because on
64-bit OSes, 32-bit processes can have the entire 4GB of VM space, but it
will make more
sense to just use 64-bit Go on those systems)
--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Loading...