www.digitalmars.com         C & C++   DMDScript  

D - non null zero length arrays

reply Mike Wynn <mike l8night.co.uk> writes:
at last I actually found a good reason why non null zero length arrays 
should exist (and a way to make them).

currently
Obj[] foo = new Obj[0];
( foo === null ) is true
Obj[] foo = new Obj[1];
foo.length = 0;
still ( foo === null ) is true

howevery with a little hacking you can do it
Obj[] makeZeroLengthArray() {
	Obj[] ar = new Obj[1];
	(cast(int*)&ar)[0] = 0;
	return ar;
}
works, and its passable and retains its non null status and 0 length :)

the returned array has a length of 0 but is not null

the reason I want this is to do the following;

I want to define a tree walking class that allows a callback if a 
specific pattern exists within the tree
the pattern is defined as the class at the root and then an array of 
what the children patterns should be (null meaning any/or none) a zero 
length array to mean no children only.
Sep 12 2003
parent reply "Matthew Wilson" <matthew stlsoft.org> writes:
 at last I actually found a good reason why non null zero length arrays
 should exist (and a way to make them).

Yikes, I'd forgotten about this. I think it doesn't make sense to not allow zero-length arrays
Sep 12 2003
next sibling parent reply Mike Wynn <mike l8night.co.uk> writes:
Matthew Wilson wrote:
at last I actually found a good reason why non null zero length arrays
should exist (and a way to make them).

Yikes, I'd forgotten about this. I think it doesn't make sense to not allow zero-length arrays

this is another case of D being driven by implementation not semantics
Sep 12 2003
parent reply Ilya Minkov <minkov cs.tum.edu> writes:
Mike Wynn wrote:
 this is another case of D being driven by implementation not semantics

Why not call it a bug? ;) -eye
Sep 13 2003
parent reply Mike Wynn <mike l8night.co.uk> writes:
Ilya Minkov wrote:
 Mike Wynn wrote:
 
 this is another case of D being driven by implementation not semantics

Why not call it a bug? ;) -eye

because it's not a bug, just a missing feature due to the design of D arrays (which are struct of length + pointer) unlike Java, where they are objects (point to a block of data with an embedded length). so in Java int[] ar = new int[n]; is is like the C typedef struct Ar_s { int length; int data[0] } Ar; Ar * new_int_array(int n) { Ar * ar = (Ar*)malloc( sizeof(Ar) + n ) ); ar->length = n; return ar; } the ( ar == null ) check is exactly that where as D .. typedef Ar_s { int length; int * data } Ar; Ar new_int_array( int n ) { Ar ar; ar.length = n; ar.data = (int*)malloc(n); return ar; } the (ar === null) check is infact (ar.data === null) as it is common for malloc(0) to return null (how can you allocate 0 bytes) this makes the D zero length non null array a little hard. either you have to allocate 1 element array (as I did) or use a non null non valid pointer (you should never be deferencing it as its 0 length) the latter does effect how to deal with int[] ar = new int[0]; ar ~= 6;
Sep 13 2003
parent Ilya Minkov <minkov cs.tum.edu> writes:
Mike Wynn wrote:
 Ilya Minkov wrote:
 Why not call it a bug? ;)


 because it's not a bug, just a missing feature due to the design of D 
 arrays (which are struct of length + pointer) unlike Java, where they 
 are objects (point to a block of data with an embedded length).
 so in Java

[Snipped away - you don't have to explain it to me :)]
 as it is common for malloc(0) to return null (how can you allocate 0 
 bytes) this makes the D zero length non null array a little hard.

Some implementations make malloc(0) be the same as malloc(1). :)))) Technically allocationg 0 bytes is a slight problem that 2 allocations would begin at the same adress, and thus would impose an ambiguity as to which of the allocations should be freed by "free".
 either you have to allocate 1 element array (as I did) or use a non null 
  non valid pointer (you should never be deferencing it as its 0 length)

 the latter does effect how to deal with
 int[] ar = new int[0];
 ar ~= 6;

Don't see how this would differ from expanding a non-allocated array - which IMO should be allowed to work... -eye
Sep 14 2003
prev sibling parent reply "Riccardo De Agostini" <riccardo.de.agostini email.it> writes:
"Matthew Wilson" <matthew stlsoft.org> ha scritto nel messaggio
news:bjtf5u$1k57$1 digitaldaemon.com...
 Yikes, I'd forgotten about this. I think it doesn't make sense to not

 zero-length arrays

Agreed. After all, even an empty string an a null string are two different beasts, ain't they? Ric
Sep 15 2003
parent reply "Matthew Wilson" <matthew stlsoft.org> writes:
"Riccardo De Agostini" <riccardo.de.agostini email.it> wrote in message
news:bk4299$1gi5$9 digitaldaemon.com...
 "Matthew Wilson" <matthew stlsoft.org> ha scritto nel messaggio
 news:bjtf5u$1k57$1 digitaldaemon.com...
 Yikes, I'd forgotten about this. I think it doesn't make sense to not

 zero-length arrays

Agreed. After all, even an empty string an a null string are two different beasts, ain't they?

They are. Alas, this is probably an argument in favour of not distinguishing between the two, since the null / empty string has caused myriad confusion (not to mention "incorrectness") in C and C++. Nonetheless, I cannot believe that an empty array will not be wanted, I've just not (yet) done enough hands-on D to produce a compelling example. However, it seems that the majority of commentators have the same gut feel about the issue that I do.
Sep 15 2003
parent reply "Riccardo De Agostini" <riccardo.de.agostini email.it> writes:
"Matthew Wilson" <matthew stlsoft.org> ha scritto nel messaggio
news:bk448p$1j2a$1 digitaldaemon.com...
 They are. Alas, this is probably an argument in favour of not

 between the two, since the null / empty string has caused myriad confusion
 (not to mention "incorrectness") in C and C++.

"Confusion" might as well be the original codename for the C RTL... So let's try not to make "Donfusion". :) Say you have a function that, given an array of customers (references to instances of a Customer class), returns an array containing references to all customers who owe me money. An empty array means I have to develop (since what I've already done has already been payed for), while a null array means I have to debug (because something must have gone wrong in the function). Obviously enough, a non-empty array just means I have to make some unpleasant phone calls... Needless to say, the function would use foreach! :) Ric
Sep 15 2003
parent reply John Boucher <John_member pathlink.com> writes:
In article <bk4bsn$1t6t$1 digitaldaemon.com>, Riccardo De Agostini says...
"Matthew Wilson" <matthew stlsoft.org> ha scritto nel messaggio
news:bk448p$1j2a$1 digitaldaemon.com...
 They are. Alas, this is probably an argument in favour of not

 between the two, since the null / empty string has caused myriad confusion
 (not to mention "incorrectness") in C and C++.

"Confusion" might as well be the original codename for the C RTL... So let's try not to make "Donfusion". :) Say you have a function that, given an array of customers (references to instances of a Customer class), returns an array containing references to all customers who owe me money. An empty array means I have to develop (since what I've already done has already been payed for), while a null array means I have to debug (because something must have gone wrong in the function). Obviously enough, a non-empty array just means I have to make some unpleasant phone calls... Needless to say, the function would use foreach! :) Ric

I've been watching this and the "pleading for String" threads, and I guess it's time I embarassed myself (further) by stepping in... If the main argument against "non-null empty arrays" is due to common problems with character arrays in C (loosely called strings) then making a String type (or class) should settle the situation and all the other types of array can be left alone, including allowing the (perhaps problematic) use of character arrays. However it's possible (nay, likely!) that I didn't quite follow the arguments closely enough. John Boucher -- Quite contrary The King had Humpty pushed.
Sep 15 2003
parent reply "Riccardo De Agostini" <riccardo.de.agostini email.it> writes:
"John Boucher" <John_member pathlink.com> ha scritto nel messaggio
news:bk4v7k$2oj9$1 digitaldaemon.com...
 If the main argument against "non-null empty arrays" is due to common

 with character arrays in C (loosely called strings) then making a String

 (or class) should settle the situation and all the other types of array

 left alone, including allowing the (perhaps problematic) use of character
 arrays.

I admit that my example was not so clear, to say the least... In short, if I write a function which returns an array of you-name-what, an empty array may be a valid return value (depending on the situation). In this case, I want to be able to distinguish between empty and null arrays, because a null could indicate a bug in my function, which I obviously want to discover and eliminate as soon as possible. Ric
Sep 16 2003
parent reply "Matthew Wilson" <matthew stlsoft.org> writes:
 I admit that my example was not so clear, to say the least...

 In short, if I write a function which returns an array of you-name-what,

 empty array may be a valid return value (depending on the situation). In
 this case, I want to be able to distinguish between empty and null arrays,
 because a null could indicate a bug in my function, which I obviously want
 to discover and eliminate as soon as possible.

I agree completely, so long as ar.length causes an access violation when ar is null. I presume this is correct?
Sep 16 2003
next sibling parent "Riccardo De Agostini" <riccardo.de.agostini email.it> writes:
"Matthew Wilson" <matthew stlsoft.org> ha scritto nel messaggio
news:bk6f8o$8d3$1 digitaldaemon.com...
 I agree completely, so long as

  ar.length

 causes an access violation when ar is null. I presume this is correct?

This is, in fact, one of the things that should help distinguishing null from empty arrays. Frankly, though, I don't know what the current behaviour is, since I don't have the time to code anything in D for now <sigh>. I wouldn't mind working 24/7 to rewrite my current project in D, but alas, it is a DOS project; besides, I'm quite late on it (as usual :) ) so time for experiments amounts to a big round zero for the time being. I'm going to start evaluating Windows XP Embedded in a few days, so I could be leaving the safe harbour of DOS in the next months... :) Ric
Sep 16 2003
prev sibling next sibling parent reply Mike Wynn <mike l8night.co.uk> writes:
Matthew Wilson wrote:
I admit that my example was not so clear, to say the least...

In short, if I write a function which returns an array of you-name-what,

an
empty array may be a valid return value (depending on the situation). In
this case, I want to be able to distinguish between empty and null arrays,
because a null could indicate a bug in my function, which I obviously want
to discover and eliminate as soon as possible.

I agree completely, so long as ar.length causes an access violation when ar is null. I presume this is correct?

you presume wrong, try dmd out! why do you want ar.length to throw an exception if ar === null ? currenlty int[] x; x = null; if ( x.length == 0) {... // no access violation (is true, the length of null array is 0) x ~= 9; // works on null. I see no reason why this should change, all that is required is x = new int[0]; if ( x === null ) { // currently this is true should no be }
Sep 16 2003
parent John Boucher <John_member pathlink.com> writes:
In article <bk7d86$44o$1 digitaldaemon.com>, Mike Wynn says...
Matthew Wilson wrote:
I admit that my example was not so clear, to say the least...

In short, if I write a function which returns an array of you-name-what,

an
empty array may be a valid return value (depending on the situation). In
this case, I want to be able to distinguish between empty and null arrays,
because a null could indicate a bug in my function, which I obviously want
to discover and eliminate as soon as possible.

I agree completely, so long as ar.length causes an access violation when ar is null. I presume this is correct?

you presume wrong, try dmd out! why do you want ar.length to throw an exception if ar === null ? currenlty int[] x; x = null; if ( x.length == 0) {... // no access violation (is true, the length of null array is 0) x ~= 9; // works on null. I see no reason why this should change, all that is required is x = new int[0]; if ( x === null ) { // currently this is true should no be }

Speaking as one who doesn't like that strlen ( nullpointer ) causes an exception, I agree that nullarray.length should not cause an exception. It's a reference to "zero" elements, so the result should be zero. Whether it causes an exception or not, most programs will still need to check for the null condition before checking the length, so there is no performance hit. Whereas, by not crashing, it allows those few programs that don't need to check to be (a little) simpler. The only conceivable downside (as far as I can tell) is if beginning programmers never get into the habit of checking for null before checking the length. John Boucher -- Quite contrary The King had Humpty pushed.
Sep 16 2003
prev sibling parent "Vathix" <vathix dprogramming.com> writes:
"Matthew Wilson" <matthew stlsoft.org> wrote in message
news:bk6f8o$8d3$1 digitaldaemon.com...
 I admit that my example was not so clear, to say the least...

 In short, if I write a function which returns an array of you-name-what,

 empty array may be a valid return value (depending on the situation). In
 this case, I want to be able to distinguish between empty and null


 because a null could indicate a bug in my function, which I obviously


 to discover and eliminate as soon as possible.

I agree completely, so long as ar.length causes an access violation when ar is null. I presume this is correct?

I don't see why this should happen, because of the way D arrays are setup, it'd be like this: uint length = 0; type* pointer = null; and expect accessing length to be AV? it's completely separate... I've always checked for an empty array by using if(!ar.length) even though it says you can do if(!ar) only because checking the length just makes more sense to me. I think we all should do this, and allow it to be non-null and still have 0 length.
Sep 16 2003