String to boolean inconsistency

Jonathan M Davis jmdavisProg at gmx.com
Sat Dec 11 19:12:30 PST 2010


On Saturday 11 December 2010 19:00:55 Jonathan M Davis wrote:
> On Saturday 11 December 2010 18:18:54 Tomek Sowiński wrote:
> > string s = "";
> > assert(s);  // ok
> > assert(s != null);  // fails
> > 
> > I guess that's a bug. But which one is right?
> 
> A null array and an empty array are essentially the same thing as far as D
> is concerned. I believe that the only difference is whether "is null"
> returns true or not. So, this program
> 
> import std.range;
> import std.stdio;
> 
> void main()
> {
>     string s = "";
> 
>     writefln("[%s]", s);
>     writeln(s is null);
>     writeln(s == null);
>     writeln(s.empty);
>     writeln();
> 
>     string t = null;
> 
>     writefln("[%s]", t);
>     writeln(t is null);
>     writeln(t == null);
>     writeln(t.empty);
> }
> 
> 
> prints
> 
> []
> false
> true
> true
> 
> []
> true
> true
> true
> 
> 
> "==" is _not_  the correct operator to use to check for null anyway. "is"
> is the correct operator for that.
> 
> This behavior is intended. Arrays are actually something like this under
> the hood:
> 
> struct array(T)
> {
>     T* arr;
>     size_t length;
> }
> 
> 
> By declaring an array to be null, all you're doing is setting arr to null.
> std.range.empty() will check length and ignore arr. "==" will presumably
> only check arr if the length of the two arrays is the same. If they are
> the same, then each element is checked fore equality. But if their length
> is zero, then you don't need to check any elements. By doing something
> like
> 
> assert("" == null)
> 
> you're likely creating an array which has whose arr value is non-null (but
> it's not actually part of the array; the memory there is extra capacity
> which will be used if/when you append to the array; it avoids extra memory
> re-allocations that way) and an array whose arr value is null. Both will
> have their lengths be 0.
> 
> When "is null" is used, it checks that arr is null. If "==" is used, it
> checks whether the elements of the two arrays are the same. Since they
> have the same length, that would mean iterating through all of their
> elements to verify that each element is the same. But since there are no
> elements in either, no elements get checked. The fact that the "" array
> has extra capacity is irrelevant. It's not part of the array, just arr.
> So, the fact that
> 
> assert("" != null);
> 
> fails is intended. It's a result of how arrays are designed.

On reflection, I should have used the name ptr instead of array, since that _is_ 
its actual name. It slipped my mind I guess...

- Jonathan M Davis


More information about the Digitalmars-d mailing list