Why Is Array.Length an Int, and Not an Uint

Why is Array.Length an int, and not an uint

Unsigned int isn't CLS compliant and would therefore restrict usage of the property to those languages that do implement a UInt.

See here:

Framework 1.1

Introduction to the .NET Framework Class Library

Framework 2.0

.NET Framework Class Library Overview

Why is C# DateTime Seconds property type int and not uint?

Using int as the default data type tend to make programming easier, since it is large enough for most common use cases, and limits the risk someone makes a mistake with unsigned arithmetic. It will often have much greater range than actually needed, but that is fine, memory is cheap, and cpus may be optimized for accessing 32-bit chunks of data.

If you wanted the most precise datatype a byte would be most appropriate, but what would you gain from using that instead of an int? There might be a point if you have millions of values, but that would be rare to store something like seconds in that way.

As mentioned in the comments, unsigned types are not CLS compliant, so will limit compatibility with other languages that do not support unsigned types. And this would be needed for a type like DateTime.

You should also prefer to use specific types over primitives. For example using TimeSpan to represent, well, a span of time.

Why does Stream.Write not take a UInt?

Unsigned types are not CLS-compliant, hence Stream.Write doesn't use uint for offset and count.

See: uint (C# Reference)

The uint type is not CLS-compliant. Use int whenever possible.

There is an old article: Why we don't have unsigned types in the CLS by Brad Abrams (2 Sep 2003) that explains the reason:

However there is one issue that keeps coming up: Why did we not allow
unsigned types (UInt32 and the like) in the CLS?

Well, there are really two answers to this question. At the first
level some languages (such as VB.NET) do not offer full support for
unsigned types.
For example you can’t have unsigned literals in
VB.NET…. But to be fair that is not a completely satisfying answer
because when we started the CLS you could not subclass in VB.NET
either, but we extended that language to support what we knew people
would want. We could have done the same thing with unsigned types.
But we didn’t. Why not? Well, that gets a deeper reason. In fact
the same reason why early betas of the C# language did not support
unsigned types (no ushort, uint and the like).

The general feeling
among many of us is that the vast majority of programming is done
with signed types. Whenever you switch to unsigned types you force a
mental model switch (and an ugly cast).
In the worst cast you build
up a whole parallel world of APIs that take unsigned types. The value
of avoiding the “< 0” check is not worth the inclusion of generics in
the CLS.

(Note that newer version of VB.Net (VB 8 onwards) supports unsigned types).

One more thing (probably unrelated) to add, Stream.Write implementation has checks for negative values:

[System.Security.SecuritySafeCritical]  // auto-generated
public override void Write(byte[] array, int offset, int count) {
if (array==null)
throw new ArgumentNullException("array", Environment.GetResourceString("ArgumentNull_Buffer"));
if (offset < 0)
throw new ArgumentOutOfRangeException("offset", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if (count < 0)
throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if (array.Length - offset < count)
throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));

BooleanArray with size larger than 2147483647

The most easy might be to use UInt as the size and then internally map 2 common BooleanArray, which use Int for addressing, despite there never could be a negative index value (this seems to be a design fault - or at least a lack of optimization). Which means, that one could as well address everything with signed Int. I mean, to internally map the negative values to one BooleanArray and the positive values to another one BooleanArray. The actual problem seems to be, that a signed Int is being passed, but only the positive range (50%) can be used to address data. One could use absoluteValue, because it doesn't matter in which direction the array is being filled.

How do I determine the size of my array in C?

Executive summary:

int a[17];
size_t n = sizeof(a)/sizeof(a[0]);

Full answer:

To determine the size of your array in bytes, you can use the sizeof
operator:

int a[17];
size_t n = sizeof(a);

On my computer, ints are 4 bytes long, so n is 68.

To determine the number of elements in the array, we can divide
the total size of the array by the size of the array element.
You could do this with the type, like this:

int a[17];
size_t n = sizeof(a) / sizeof(int);

and get the proper answer (68 / 4 = 17), but if the type of
a changed you would have a nasty bug if you forgot to change
the sizeof(int) as well.

So the preferred divisor is sizeof(a[0]) or the equivalent sizeof(*a), the size of the first element of the array.

int a[17];
size_t n = sizeof(a) / sizeof(a[0]);

Another advantage is that you can now easily parameterize
the array name in a macro and get:

#define NELEMS(x)  (sizeof(x) / sizeof((x)[0]))

int a[17];
size_t n = NELEMS(a);

If free() knows the length of my array, why can't I ask for it in my own code?

Besides Klatchko's correct point that the standard does not provide for it, real malloc/free implementations often allocate more space then you ask for. E.g. if you ask for 12 bytes it may provide 16 (see A Memory Allocator, which notes that 16 is a common size). So it doesn't need to know you asked for 12 bytes, just that it gave you a 16-byte chunk.

Java determining array size in an unknown array via reflection

So what I did to resolve this was to create a faux instance of the object by:

Class.forName(topicName).getConstructor().newInstance()

and I passed that into the a.get() to find array length.



Related Topics



Leave a reply



Submit