Forbid dynamic arrays in boolean evaluation contexts

Steven Schveighoffer schveiguy at yahoo.com
Mon Mar 25 20:58:35 PDT 2013


On Mon, 25 Mar 2013 22:21:47 -0400, Vladimir Panteleev  
<vladimir at thecybershadow.net> wrote:

> On Tuesday, 26 March 2013 at 01:57:10 UTC, Steven Schveighoffer wrote:
>> On Mon, 25 Mar 2013 17:28:51 -0400, Vladimir Panteleev  
>> <vladimir at thecybershadow.net> wrote:
>>
>>> On Monday, 25 March 2013 at 14:46:27 UTC, Steven Schveighoffer wrote:
>>>> I would favor just changing the behavior.
>>>
>>> That would silently break my code.
>>
>> It would seem incomplete not to have if(arr) work, and the way it works  
>> now is very error prone.
>>
>> You would have to change your code either way.  Deprecating than  
>> reintroducing seems gratuitous to me.  Most people do not use if(arr)  
>> to check for array pointer when if(arr.ptr) is more descriptive.
>>
>> How much do you use this "feature"?  Can they simply be replaced with  
>> if(arr.ptr)? or are they more of the type Jacob has with if(auto a =  
>> getArray())?  I'm trying to get a feel for how much breakage this  
>> causes, as I typically do not use that construct.
>
> No, it's nothing like that. In fact, it's very simple:
>
> Users will download my open-source program, compile it successfully,  
> then try using it - at which point, it will crash, produce incorrect  
> output, or do something equally bad. Would you not agree that this is  
> unacceptable?

Well, it's unacceptable as long as the code is not updated, or you caveat  
it by saying it only was tested on compiler version X or earlier.  If we  
go through a deprecation cycle, and then reintroduce if(arr) to mean  
if(arr.length), then we are in the same situation as long as you haven't  
updated your code.

> Furthermore, I would have no way to automatically find all places where  
> I would need to change my code. I would need to look at every if  
> statement of my program and see if its behavior depends on whether the  
> string/array is empty or null. My program is quite large, so, again,  
> this is unacceptable.

That I agree is unacceptable.  We would have to take the unusual step of  
having a tool/compiler flag to identify the places this happens.  Asking  
people to review their code by hand is not what I had in mind.

> I use this feature in the same way that anyone uses a nullable type.  
> It's the same distinction between a pointer to struct that is null, or  
> that is pointing to an instance containing the struct's .init. It's the  
> same distinction between a value type T and the benefits of Nullable!T.  
> "null" is usually used to indicate the absence of a value, as opposed to  
> an empty value.

The breaking distinction is between null and a non-null empty string.  In  
the cases where the code is setting a non-empty array, this is not an  
issue.  This is why I asked about usage.  It may turn out that you are  
checking for null, but really because when the value is set, it's never  
empty, it's not an issue.

> Although I can see how this can trip up new users of D, personally I  
> prefer things to be just the way they are now. That said, I wouldn't be  
> against forcing one to write "s is null", if the consensus was that this  
> would improve D.

I understand the idea to use null as a "special" array value.  But the  
truth is, nulls act just like empty arrays in almost all aspects.

The critical failure I see is this:

int *p = null;
if(p == null) is equivalent to if(!p) and if(p != null) is equivalent to  
if(p).

But for arrays:

int[] a = null;
if(a == null) is NOT equivalent to if(!a), and if(a != null) is NOT  
equivalent to if(a).  This is the part that screws up so many people.   
Because == does not do the same thing, we have a quirk that is silent and  
deadly.  It's made even worse that for MOST cases, if(!a) is equivalent to  
if(a == null).  So it's very easy to miss this critical distinction, and  
it's not at all intuitive.

-Steve


More information about the Digitalmars-d mailing list