Jump to page: 1 2 3
Thread overview
empty arrays and cast(bool): WAT
Feb 19, 2012
Timon Gehr
Feb 19, 2012
bearophile
Feb 19, 2012
Timon Gehr
Feb 19, 2012
Jonathan M Davis
Feb 19, 2012
Timon Gehr
Feb 19, 2012
Jonathan M Davis
Feb 19, 2012
Bernard Helyer
Feb 19, 2012
Timon Gehr
Feb 19, 2012
Timon Gehr
Feb 19, 2012
Bernard Helyer
Feb 19, 2012
Timon Gehr
Feb 19, 2012
Jonathan M Davis
Feb 19, 2012
Jonathan M Davis
Feb 19, 2012
Timon Gehr
Feb 19, 2012
Jonathan M Davis
Feb 19, 2012
Timon Gehr
Feb 19, 2012
Jonathan M Davis
Feb 19, 2012
bearophile
Feb 19, 2012
Timon Gehr
Feb 19, 2012
Daniel Murphy
Feb 22, 2012
Regan Heath
Feb 22, 2012
bearophile
Feb 22, 2012
H. S. Teoh
February 19, 2012
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
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
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
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
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
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
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
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
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
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