Thread overview
array !is null fails
Feb 13, 2007
BCS
Feb 13, 2007
John Demme
Feb 13, 2007
BCS
Feb 13, 2007
BCS
Feb 13, 2007
Frits van Bommel
Feb 13, 2007
BCS
Feb 13, 2007
Frits van Bommel
Feb 13, 2007
BCS
February 13, 2007
this works:

assert((cast(char*)null)[0..0] !is null);

this dosn't

assert((cast(char*)null)[0..10] !is null);

DMD v1.005 linux

Am I missing somthing?


February 13, 2007
BCS wrote:

> this works:
> 
> assert((cast(char*)null)[0..0] !is null);
> 
> this dosn't
> 
> assert((cast(char*)null)[0..10] !is null);
> 
> DMD v1.005 linux
> 
> Am I missing somthing?

Seems like a safety thing to me.  If an array has a non-zero length, the still points at null, you shouldn't be looking at it.  A zero length array is always valid, however.  A zero-length array is still an array, not null... depending on your definition.

Dunno what the implications of such a discontinuity are, but you could just use .ptr or (!is null && .length > 0) if you want.

-- 
~John Demme
me@teqdruid.com
http://www.teqdruid.com/
February 13, 2007
Reply to John,

> BCS wrote:
> 
>> this works:
>> 
>> assert((cast(char*)null)[0..0] !is null);
>> 
>> this dosn't
>> 
>> assert((cast(char*)null)[0..10] !is null);
>> 
>> DMD v1.005 linux
>> 
>> Am I missing somthing?
>> 
> Seems like a safety thing to me.  If an array has a non-zero length,
> the still points at null, you shouldn't be looking at it.

That's why it's in the assert

>  A zero
> length array is always valid, however.  A zero-length array is still
> an array, not null... depending on your definition.
> 

Ah... I though that [i..i].length == 1? 

> Dunno what the implications of such a discontinuity are, but you could
> just use .ptr or (!is null && .length > 0) if you want.
> 

What good is the (array !is null) if it doesn't tell you when the pointer is null?


February 13, 2007
"BCS" <ao@pathlink.com> wrote in message news:ce0a334373d48c91d12a1b9c0ec@news.digitalmars.com...
> Ah... I though that [i..i].length == 1?

Nope, since the second index is noninclusive, [i..i + 1] will be one element (just i), and [i..i] is 0.

> What good is the (array !is null) if it doesn't tell you when the pointer is null?

Well if you want to see if the pointer is null then use "if(array.ptr is null)".  Though I'll agree with you that the discontinuity between zero-length null pointer arrays and more-than-zero-length null pointer arrays is a bit odd.


February 13, 2007
Reply to Jarrett,

> "BCS" <ao@pathlink.com> wrote in message
> news:ce0a334373d48c91d12a1b9c0ec@news.digitalmars.com...
> 
>> Ah... I though that [i..i].length == 1?
>> 
> Nope, since the second index is noninclusive, [i..i + 1] will be one
> element (just i), and [i..i] is 0.

Oh, Duh. And I've had to correct others on that one  :b

> 
>> What good is the (array !is null) if it doesn't tell you when the
>> pointer is null?
>> 
> Well if you want to see if the pointer is null then use "if(array.ptr
> is null)".  Though I'll agree with you that the discontinuity between
> zero-length null pointer arrays and more-than-zero-length null pointer
> arrays is a bit odd.
> 

What else could be null? I don't see anything else that it could mean other than "is the pointer null".


February 13, 2007
BCS wrote:
> Reply to Jarrett,
> 
>> "BCS" <ao@pathlink.com> wrote in message
>> news:ce0a334373d48c91d12a1b9c0ec@news.digitalmars.com...
>>
>>> What good is the (array !is null) if it doesn't tell you when the
>>> pointer is null?
>>>
>> Well if you want to see if the pointer is null then use "if(array.ptr
>> is null)".  Though I'll agree with you that the discontinuity between
>> zero-length null pointer arrays and more-than-zero-length null pointer
>> arrays is a bit odd.
>>
> What else could be null? I don't see anything else that it could mean other than "is the pointer null".

'null', when interpreted as an array, is an _empty_ array with the pointer being null.

This allows it to be a reasonable default initializer for dynamic arrays, and means (arr == null) checks whether the array is empty.
February 13, 2007
Frits van Bommel wrote:
> BCS wrote:
> 
>> Reply to Jarrett,
>>
>>> "BCS" <ao@pathlink.com> wrote in message
>>> news:ce0a334373d48c91d12a1b9c0ec@news.digitalmars.com...
>>>
>>>> What good is the (array !is null) if it doesn't tell you when the
>>>> pointer is null?
>>>>
>>> Well if you want to see if the pointer is null then use "if(array.ptr
>>> is null)".  Though I'll agree with you that the discontinuity between
>>> zero-length null pointer arrays and more-than-zero-length null pointer
>>> arrays is a bit odd.
>>>
>> What else could be null? I don't see anything else that it could mean other than "is the pointer null".
> 
> 
> 'null', when interpreted as an array, is an _empty_ array with the pointer being null.
> 
> This allows it to be a reasonable default initializer for dynamic arrays, and means (arr == null) checks whether the array is empty.

Ok, I see that. But aren't the vast majority of comparisons ageist null asking "Is this readable?" That is the meaning I would expect. Then again it does bring in a corner case (length checked iff ptr!=null).

It's quite a bother though.

void fn(char[] c)
{

	//works untill c.ptr == null && c.length != 0

	assert(c !is null);
	writef("%s\n", c);
}
February 13, 2007
BCS wrote:
> Frits van Bommel wrote:
>> 'null', when interpreted as an array, is an _empty_ array with the pointer being null.
>>
>> This allows it to be a reasonable default initializer for dynamic arrays, and means (arr == null) checks whether the array is empty.
> 
> Ok, I see that. But aren't the vast majority of comparisons ageist null asking "Is this readable?" That is the meaning I would expect. Then again it does bring in a corner case (length checked iff ptr!=null).
> 
> It's quite a bother though.
> 
> void fn(char[] c)
> {
> 
>     //works untill c.ptr == null && c.length != 0
> 
>     assert(c !is null);
>     writef("%s\n", c);
> }

I'd argue that if you have an array with a non-zero length but null pointer, you've already messed up somewhere. It should have been checked at whatever place sliced the null pointer. (The only way to obtain such an array would be either slicing a raw pointer or using pointer casts/unions to access memory as a different type than it actually is, right?)

And it'd get even worse if you take a non-empty slice from such an array that doesn't start at index 0. Then you have'd an array with non-zero length and non-null pointer that is nevertheless very much invalid, and without any way to detect it[1].



[1]: That is, short of indexing it and detecting the segfault/access violation caused, or resorting to system-dependent checks like "is it in the first page of memory".
February 13, 2007
Frits van Bommel wrote:
> 
> 
> I'd argue that if you have an array with a non-zero length but null pointer, you've already messed up somewhere. It should have been checked at whatever place sliced the null pointer.

Yup. But then again asserts should be used to check stuff you otherwise can't control (incoming arguments and returns from 3rd party code etc.)

I go by the assumption that if an assert *ever* trips then, by definition, you have a bug (unless you are trying to trip it in a unittest or something).

Conditions that might happen without bugs should be handled with exceptions.

> (The only way to obtain such an array would be either slicing a raw pointer or using pointer casts/unions to access memory as a different type than it actually is, right?)
> 
> And it'd get even worse if you take a non-empty slice from such an array that doesn't start at index 0. Then you have'd an array with non-zero length and non-null pointer that is nevertheless very much invalid, and without any way to detect it[1].
> 

Maybe there should be a gc.IsValid(void[]) function that returns true if  the full length of the array is readable (or is GC allocated if the first is to hard).

I wonder what it would take to make asserts do that check when given an array.

char[] c
assert(c); // is c "good"?


> 
> 
> [1]: That is, short of indexing it and detecting the segfault/access violation caused, or resorting to system-dependent checks like "is it in the first page of memory".