Checking if a string is null

Derek Parnell derek at psyc.ward
Wed Jul 25 23:22:00 PDT 2007

On Thu, 26 Jul 2007 07:47:03 +0200, Frits van Bommel wrote:

> Derek Parnell wrote:
>> On Wed, 25 Jul 2007 19:01:57 +0200, Frits van Bommel wrote:
>>> Since null arrays have length 0, they *are* empty arrays :P.
>> Not in my world. I see that null arrays have no length. That is to say, the
>> do not have any length, which is different from saying they have a length
>> and that length is zero.
> But the fact of the matter is, 'T[] x = null;' reserves space for the 
> .length and sets it to 0. If you have a suggestion for a different value 
> to put there, by all means make it.

I'm trying not to set in concrete the ABI of variable-length arrays. So
even though the current D definition is that a VL array consists of a
two-element struct and zero or one block of RAM, conceptually a null array
doesn't point to anything and does not have a length. So to me it doesn't
matter that D allocates space for .length and .ptr portions of the nullVL
array, because it still should not use the .length value. But, because
theoretically every RAM address possbiel could be stored in the .ptr
portion, including zero, I conceed that in D the .ptr and .length both
being zero is needed to indicate a null array, even though this disallows
the conceptual empty array begining at address zero.

> Or would you prefer a segfault or diagnostic when accessing 
> (cast(T[])null).length? That'd introduce overhead on every .length 
> access (unless the compiler can statically determine whether an array 
> reference is null).

Yes I would. However, too many people are relying on this inconsistency so
I'll live with that wart in the language.

>>>> All that I would like changed is for the compare, in the case of length 
>>>> == 0, to check the data pointers, eg.
>>>>  > int opEquals(T)(T[] u, T[] v) {
>>>>  >     if (u.length != v.length) return false;
>>>>       if (u.length == 0) return (u.ptr == v.ptr);
>>>>  >     for (size_t i = 0; i < u.length; i++) {
>>>>  >         if (u[i] != v[i]) return false;
>>>>  >     }
>>>>  >     return true;
>>>>  > }
>>>> This should mean "" == "" but not "" == null, likewise null == null but 
>>>> not null == "".
>>> Let's look at this code:
>>> ---
>>> import std.stdio;
>>> void main()
>>> {
>>>      char[][] strings = ["hello world!", "", null];
>>>      foreach (str; strings) {
>>>          auto str2 = str.dup;
>>>          if (str == str2)
>>>              writefln(`"%s" == "%s" (%s, %s)`, str, str2, str.ptr, 
>>> str2.ptr);
>>>          else
>>>              writefln(`"%s" != "%s" (%s, %s)`, str, str2, str.ptr, 
>>> str2.ptr);
>>>      }
>>> }
>>> ---
>>> The output is currently (on my machine):
>>> =====
>>> "hello world!" == "hello world!" (805BE60, F7CFBFE0)
>>> "" == "" (805BE78, 0000)
>>> "" == "" (0000, 0000)
>>> =====
>>> Your change would change the second line (even if it actually allocated 
>>> a new empty string like you probably want instead of returning null). 
>>> How would that be consistent in any way?
>> Your example is misleading for at least two reasons:
>> ** The '==' operator compares the contents of the strings. A null string
>> has no content so there is nothing to compare. This should fail but is
>> doesn't in the current D. It should fail in the same manner that a null
>> object reference fails the '==' operator.
> This wasn't the point of the example. 

Sorry for misunderstanding.

> I could have left out the third 
> element and change the .dup in the second line to a different empty 
> string (f.e. a 0-length slice of the first one) and the point would 
> remain the same: the proposed change would break comparison by '==' for 
> empty non-null strings.

I agree with you. Two empty non-null strings should compare as equal
because the equality test is against the contents of the array and not the
addresses of the array. A null array has no content so one has nothing to
compare it with; this is why I think that it is an illegal/meaningless

Derek Parnell
Melbourne, Australia
"Down with mediocrity!"

More information about the Digitalmars-d-learn mailing list