View mode: basic / threaded / horizontal-split · Log in · Help
February 19, 2012
empty arrays and cast(bool): WAT
Why does the following code behave funny?

void main(){
    string x = " "[1..1];
    writeln(cast(bool)x); // true
    char[] y = [' '][1..1];
    writeln(cast(bool)y); // false
}

Is there any reason for empty arrays to evaluate to true? This is very 
bug prone.
February 19, 2012
Re: empty arrays and cast(bool): WAT
Timon Gehr:

> Is there any reason for empty arrays to evaluate to true? This is very 
> bug prone.

Related?
http://d.puremagic.com/issues/show_bug.cgi?id=4733

Bye,
bearophile
February 19, 2012
Re: empty arrays and cast(bool): WAT
On Sunday, February 19, 2012 03:01:55 Timon Gehr wrote:
> Why does the following code behave funny?
> 
> void main(){
>      string x = " "[1..1];
>      writeln(cast(bool)x); // true
>      char[] y = [' '][1..1];
>      writeln(cast(bool)y); // false
> }
> 
> Is there any reason for empty arrays to evaluate to true? This is very
> bug prone.

Because they're not null. _null_ is what evaluates to false, not an empty 
array. But the fact that == treats null and [] as the same thing _does_ 
understandably cloud things a bit.

But

if(arr)

is lowered to

if(cast(bool)arr)

which checks for null, not empty. So, this is fully expected. If you want to 
check whether an array is empty, then check whether it's empty, not whether 
it's true.

- Jonathan M Davis
February 19, 2012
Re: empty arrays and cast(bool): WAT
On 02/19/2012 03:24 AM, bearophile wrote:
> Timon Gehr:
>
>> Is there any reason for empty arrays to evaluate to true? This is very
>> bug prone.
>
> Related?
> http://d.puremagic.com/issues/show_bug.cgi?id=4733
>
> Bye,
> bearophile

Roughly. I want it to be allowed, but to test the length instead of ptr.
February 19, 2012
Re: empty arrays and cast(bool): WAT
On Sunday, February 19, 2012 04:13:02 Timon Gehr wrote:
> On 02/19/2012 03:24 AM, bearophile wrote:
> > Timon Gehr:
> >> Is there any reason for empty arrays to evaluate to true? This is very
> >> bug prone.
> > 
> > Related?
> > http://d.puremagic.com/issues/show_bug.cgi?id=4733
> > 
> > Bye,
> > bearophile
> 
> Roughly. I want it to be allowed, but to test the length instead of ptr.

That would potentially break code. It also makes arrays less consistent with 
other types that can be null, but the weirdness with [] == null already does 
that on some level.

My general take on it is that you should just be aware that you need to use 
arr.empty when you mean empty and arr !is null when you mean null. So,

if(arr)

is the kind of code that should just be avoided with arrays.

- Jonathan M Davis
February 19, 2012
Re: empty arrays and cast(bool): WAT
On 02/19/2012 03:23 AM, Jonathan M Davis wrote:
> On Sunday, February 19, 2012 03:01:55 Timon Gehr wrote:
>> Why does the following code behave funny?
>>
>> void main(){
>>       string x = " "[1..1];
>>       writeln(cast(bool)x); // true
>>       char[] y = [' '][1..1];
>>       writeln(cast(bool)y); // false
>> }
>>
>> Is there any reason for empty arrays to evaluate to true? This is very
>> bug prone.
>
> Because they're not null. _null_ is what evaluates to false, not an empty
> array.

That is my point. It should not be that way. That is utter nonsense. It 
is a major wart. (Every literal with a null .ptr evaluates to false, 
btw, not just 'null')

> But the fact that == treats null and [] as the same thing _does_
> understandably cloud things a bit.
>

Nothing cloudy about that, that is sane behaviour and I want it to be 
consistently carried out everywhere. ('is' can still do a binary 
compare, that is what it is designed to do.)

> But
>
> if(arr)
>
> is lowered to
>
> if(cast(bool)arr)
>
> which checks for null, not empty. So, this is fully expected.

No, it is not what is expected, it is what is _observed_. It is almost 
certainly just a bug in the implementation and everyone thought it is 
part of the language.

Consider this, and then don't tell me it is not a leftover from the 
ancient times when dynamic arrays implicitly converted to their .ptr fields:

struct DynArray{
    size_t length;
    int* ptr;
    alias ptr this;
}
void main(){
    DynArray a;
    int[] b;
    writeln(cast(bool)a); // false
    writeln(cast(bool)b); // false

    a.ptr = new	int;
    writeln(cast(bool)a); // true

    *(cast(int**)&b+1) = new int; // "b.ptr = new int"
    writeln(cast(bool)b); // true
}


> If you want to check whether an array is empty, then check whether it's empty, not whether
> it's true.
>

I can't help myself noticing that you always seem to defend the position 
that makes the code more verbose.
February 19, 2012
Re: empty arrays and cast(bool): WAT
On 02/19/2012 04:17 AM, Jonathan M Davis wrote:
> On Sunday, February 19, 2012 04:13:02 Timon Gehr wrote:
>> On 02/19/2012 03:24 AM, bearophile wrote:
>>> Timon Gehr:
>>>> Is there any reason for empty arrays to evaluate to true? This is very
>>>> bug prone.
>>>
>>> Related?
>>> http://d.puremagic.com/issues/show_bug.cgi?id=4733
>>>
>>> Bye,
>>> bearophile
>>
>> Roughly. I want it to be allowed, but to test the length instead of ptr.
>
> That would potentially break code.

It would also potentially fix code.

> It also makes arrays less consistent with
> other types that can be null,

If so, then in a good way.

> but the weirdness with [] == null already does
> that on some level.
>

If you think that is weird, consider this:

static assert([1,2,3] == [1,2,3]);


> My general take on it is that you should just be aware that you need to use
> arr.empty when you mean empty and arr !is null when you mean null. So,
>
> if(arr)
>
> is the kind of code that should just be avoided with arrays.
>

Why? (step back a moment and stop thinking about what you know about 
DMDs implementation semantics and then answer)
February 19, 2012
Re: empty arrays and cast(bool): WAT
On Sunday, February 19, 2012 04:24:46 Timon Gehr wrote:
> > But the fact that == treats null and [] as the same thing _does_
> > understandably cloud things a bit.
> 
> Nothing cloudy about that, that is sane behaviour and I want it to be
> consistently carried out everywhere. ('is' can still do a binary
> compare, that is what it is designed to do.)

It's lunacy IMHO. null and empty should _never_ have been conflated. They are 
two separate concepts. _That_ is a major wart in the language IMHO. We would 
have better off to not have null arrays at all than this halfway nonsense. But 
that ship sailed ages ago.

> I can't help myself noticing that you always seem to defend the position
> that makes the code more verbose.

I hadn't noticed. If that's true, it's probably because it's more explicit. 
And with arrays, I don't trust them with regards to this sort of stuff 
precisely because null and empty have been conflated. So, I check for what I 
mean, whether that's null or empty. And I consider code like arr == null to be 
sign that someone doesn't know what they're doing. Someone who understands how 
arrays work in D should either be doing arr.empty or arr.length == 0 if 
they're checking for empty and arr is null if they're checking for null.

- Jonathan M Davis
February 19, 2012
Re: empty arrays and cast(bool): WAT
On Sunday, February 19, 2012 04:33:14 Timon Gehr wrote:
> Why? (step back a moment and stop thinking about what you know about
> DMDs implementation semantics and then answer)

Because of the whole nonsense of null and empty being treated the same in some 
circumstances and not in others. I'm immediately suspicious of any arry code 
which doesn't expcitly check for empty or null but relies on stuff like 
cast(bool)arr. The odds are too high that the programmer meant one and got the 
other.

- Jonathan M Davis
February 19, 2012
Re: empty arrays and cast(bool): WAT
On 02/19/2012 04:38 AM, Jonathan M Davis wrote:
> On Sunday, February 19, 2012 04:24:46 Timon Gehr wrote:
>>> But the fact that == treats null and [] as the same thing _does_
>>> understandably cloud things a bit.
>>
>> Nothing cloudy about that, that is sane behaviour and I want it to be
>> consistently carried out everywhere. ('is' can still do a binary
>> compare, that is what it is designed to do.)
>
> It's lunacy IMHO. null and empty should _never_ have been conflated. They are
> two separate concepts. _That_ is a major wart in the language IMHO. We would
> have better off to not have null arrays at all than this halfway nonsense.

Agreed. I don't mind having it as a special value, but it should not 
have as far reaching consequences as it does right now.

> But that ship sailed ages ago.
>
>> I can't help myself noticing that you always seem to defend the position
>> that makes the code more verbose.
>
> I hadn't noticed. If that's true, it's probably because it's more explicit.

Ok.

> And with arrays, I don't trust them with regards to this sort of stuff
> precisely because null and empty have been conflated. So, I check for what I
> mean, whether that's null or empty. And I consider code like arr == null to be
> sign that someone doesn't know what they're doing.

Indeed. I have never needed arr == null. Comparing class references to 
null using '==' is illegal. Probably the same could be done for arrays. 
Would also increase consistency.

> Someone who understands how arrays work in D should either be doing arr.empty or arr.length == 0 if
> they're checking for empty and arr is null if they're checking for null.
>
> - Jonathan M Davis

That is true. It is also what worries me. Having cast(bool) evaluate to 
false for empty arrays is intuitive and has massive precedent in other 
programming languages.
« First   ‹ Prev
1 2 3
Top | Discussion index | About this forum | D home