Checking if a string is null
Frits van Bommel
fvbommel at REMwOVExCAPSs.nl
Wed Jul 25 10:01:57 PDT 2007
Regan Heath wrote:
>>> I'm in the 'distinguishable' camp. I can see the merit. At the very
>>> least it should be consistent!
>>
>> They *are* distinguishable. That's why above code returns different
>> results for the 'is' comparison...
>
> True. I guess what I meant to say was I'm in the '3 distict states'
> camp (which may be a camp of 1 for all I know). See my reply to
> digitalmars.D for a definition of the 3 states.
>
>> I for one am perfectly fine with "cast(char[]) null" meaning ".length
>> == 0 && .ptr == null"
>
> Same here.
>
> > and with comparisons of arrays using == and friends
>> only inspecting the contents (not location) of the data.
>
> I don't think an empty string (non-null, length == 0) should compare
> equal to a non-existant string (null, length == 0). And vice-versa.
>
> The only thing that should compare equal to null is null. Likewise an
> empty array should only compare equal to another empty array.
>
> My reasoning for this is consistency, see at end.
Since null arrays have length 0, they *are* empty arrays :P.
> Aside: If the location and length are identical you can short-circuit
> the compare, returning true and ignoring the content, this could save a
> bit of time on comparisons of large arrays.
At least with that last paragraph I can agree ;)
Now, about this:
> 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?
(Same goes for other ways to create different-ptr empty strings)
What you might have meant on that extra line might be more like:
---
if (u.length == 0) return ((u.ptr is null) == (v.ptr is null));
---
which will return true if both .ptr values are null or both are non-null.
More information about the Digitalmars-d-learn
mailing list