[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [ProgSoc] Programming! Code!



On Friday 20 October 2006 02:39, Roland Turner wrote:
> On Thu, 2006-10-19 at 21:03 +1000, Nigel Sheridan-Smith wrote:
> > > Interesting; spec# claims to add non-null types, but your test
> > > suggests that even System.Boolean is already non-null.
> > >
> > > Oh well, syntax trivia...
> >
> > Maybe by "non-null" they mean objects that can never be null (in
> > valid code). Constants without being constant?
>
> Your test suggests that Boolean already cannot be null in C#. I'm not
> sure what you mean by "constants without being constant".

Values of type Boolean can not be null in C#. 'null', in C#, refers to 
a 'null reference'. A value types are not reference type the 
possibility of them being 'null' is nonsensical.

Value types are not reference types. They are very similar to 'struct' 
in C++, they can be allocated (automatically) on the stack (life time 
managed by scope) or they can be allocated (automatically) on the heap. 
There are three modes of heap allocation of value types which spring to 
mind:

 1. As a class member

 class C {
   Int32 a;
 }

 C o = new C();

In this cases the value a of value type Int32 is allocated 32-bits of 
storage on the managed heap. This 32-bits will be 'inside' the object o 
of reference type C.

Internally o is a managed pointer (a 'reference' to a class instance 
allocated on the managed heap and track by GC).

All in all the above class will consume 32 bits of data for its a value 
and a number of bytes for its 'object header' (I forget how big the 
object header is... but that's where an instance keep the 'back 
pointers' to its type system meta data). As an implementation detail 
the value of the pointer stored in o will be pointing at a. The object 
header is offset back from that by a few bytes (but that's just what 
I've heard, and is purely an implementation detail -- makes sense from 
a perf perspective though).

 2. In an array slot

 Int32[] a = { 1, 2, 3 };

Int32[] is a reference type. That is, a pointer to an instance of 
reference type Int32[] is stored in a. As a is a reference type it has 
been allocated on the managed heap and has an object header. In terms 
of storage the above code is conceptually identical to this:

 class A {
   Int32 a1, a2, a3;
 }

However, the size of the array is not 'fixed' in the first line, where 
as it is fixed in the class A example.

This is valid in C#:

 Int32[] a = { 1, 2, 3, 4 };
 assert( a.Length == 4 );
 a = new Int32[] { 1, 2, 3, 4, 5 };
 assert( a.Length == 5 );

 3. In a boxed class

In this case the CLR provides an automatic facility for allocating a 
value type in a 'stub' class on the heap. I imagine you understand how 
boxing works. But basically it's like this:

 struct S {
   public readonly Int32 V;
   public S( Int32 v ) { V = v; }
 }

 class C {
   public readonly S S;
   public C( S s ) { S = s; }
 }

 S s = new S( 123 ); // allocates an unboxed value on the stack
 C c = new C( s );   // equivalent of 'boxing' a value, now allocated
                     // as a readonly member of c on the managed heap
 S v = c.S;          // equivalent of 'unboxing'. copies the value
                     // from the heap into the value v on the stack

> > Ahhh more reading...
> >
> > .NET 2.0 adds Nullable types, so you can explicitly add "null" as a
> > valid value to the value types. Presumably this is used for RDBMS.
>
> If I'm getting this right (I'm still finding it difficult to
> believe), then C# is the first widely-used OO language that I've
> encountered which does not have null object references (explicit
> references to no object). This is not quite the same as "null" (the
> complete absence of a value, rather than an explicit reference to no
> value) in a relation, but the two can be and frequently are readily
> mapped onto each other.

Value types have never been able to contain a null value in any CLR 
language, including VB7 and C# 1.0.

The problem with mapping 'null' to 'NULL' is in the decision about 
whether to implement TVL or not. assert( null == null )?

> The other place that it's frequently useful in Java is to explicitly
> represent intentional absence of a value, e.g. for a "don't know" or
> "not specified" situation; a Boolean object reference can, by virtue
> of being an object reference, be a null object reference (a explicit
> reference to no object) and, therefore, explicitly represent the
> absence of a value. "boolean" on the other hand is a primitive value
> type (not a reference) and, therefore, cannot be "null" in either
> sense.

You statements regarding what can and can not be done here are 
incorrect.











-
You are subscribed to the progsoc mailing list. To unsubscribe, send a
message containing "unsubscribe" to progsoc-request@xxxxxxxxxxxxxxxxxxx
If you are having trouble, ask owner-progsoc@xxxxxxxxxxxxxxxxxx for help.