Empty Array is Null?

Steven Schveighoffer schveiguy at yahoo.com
Wed Mar 19 10:08:24 PDT 2008


"Frits van Bommel" wrote
> Steven Schveighoffer wrote:
>> "Brian White" wrote
>>> char[] array = "".dup;
>>> assert(array !is null);
>>>
>>> This will exit because the assert condition is false.
>>>
>>> Why is that?
>>
>> Here is my guess:
>>
>> The compiler does not allocate a piece of memory for "", and so the array 
>> struct for it looks like:
>>
>> { ptr = null, length = 0 }
>
> Sorry, but your guess is wrong:
> ---
> urxae at urxae:~/tmp$ cat test.d
> import std.stdio;
>
> void main() {
>     writefln("%s", "".ptr);
> }
> urxae at urxae:~/tmp$ dmd -run test.d
> 805C41C

Hm... ok, like I said it was a guess :)

> On top of all that, it's also very efficient since it doesn't require any 
> allocation (at least, until anything is appended onto it).
> The *only* property it doesn't have that 'normal' .dups do have is that 
> normal .dups return unique non-null values. The only ways to even detect 
> that are by 'is'-comparing to null (or a null-valued array) or (implicitly 
> or explicitly) casting it to a boolean. All other behavior is completely 
> consistent.
> The discussion on the NGs was, IIRC, between those who considered 'null' 
> to mean "no string" while considering other empty strings as "empty 
> string" and those who just don't see any reason to explicitly distinguish 
> between the two. In the end, I believe, it came down to "Walter is in the 
> latter camp".

My view is that array is null should not compile, as array is not a pointer 
type.  Having statements like this confuses new coders into thinking array 
is a pure pointer or reference type, when in fact it is a struct.  This is 
espeically confusing to Java or C# (and probably other) coders who are used 
to an array being a heap-allocated type.

But I seriously doubt my view is going to change anything like others before 
me :)

> Actually, if you compare an array to null (using 'is') DMD performs an 
> 'or' instruction on the .ptr and .length and tests for the flag that it 
> sets if the result is zero. This is just an optimization; this is 
> equivalent to checking if both .ptr and .length are 0 (though presumably 
> faster, since it's a single instruction that doesn't even implement full 
> comparison).

Huh?  Why does it do that?  If you have a null pointer, then clearly the 
length should be 0.  An optimization in my mind would be to just replace 
array is null to array.ptr is null.  Is there a good reason to have a null 
pointer array with a non-zero length?

>
>> The sucky part about all this is that if you have an empty array where 
>> the pointer is NOT null, then you get a different result (that array is 
>> not considered to be null)
>
> Actually, 'array == null' should return true for any empty array. Testing 
> arrays with 'is' explicitly requests comparing .ptr and .length directly, 
> not paying any attention to the contents; 'is' checks for identity, '==' 
> for equivalence.

I would guess that the newest D compiler would not allow that, since 
comparing to null is now an error except for using 'x is null'

Of course, this is another guess, since I haven't downloaded the new 
compiler yet :)

-Steve 




More information about the Digitalmars-d-learn mailing list