Forbid dynamic arrays in boolean evaluation contexts

Vladimir Panteleev vladimir at thecybershadow.net
Tue Mar 26 04:42:02 PDT 2013


On Tuesday, 26 March 2013 at 03:58:35 UTC, Steven Schveighoffer 
wrote:
> 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.

That's horrible. What ever happened to fail-fast?

> 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.

The deprecation process takes years. This is a distinction much 
bigger than two consecutive compiler versions.

Also, D still sticks to the "if it looks like C, then it must 
work like C or fail to compile" principle. It's there for a 
reason, and I think the same reason applies to older versions of 
D.

>> 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.

Even if you introduce a new flag, people may only catch the 
problem too late. A routine software upgrade (as by an OS's 
package manager) should not cause incorrect output that late in 
the cycle!

> 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.

Yes; to clarify, the program in question handles input that is 
often an empty string or array. In these cases, the length of the 
data is not important - it's just user data, regardless of its 
length. Its presence or absence is important.

> 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.

Yes, but your argument is based on using the equality (==) 
operator. This operator can do special things in certain cases. 
When you have a C string and a D string, the == operator will do 
very different things, so pointing out that its behavior is 
different when the pointer / .ptr is null, when its behavior is 
also different when the pointer / .ptr is non-null, is not much 
of an argument.

The behavior is consistent with the identity (is) operator.

> 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.

Is it? If a was an object, that would invoke opEquals. I believe 
"a is null" is a more accurate equivalent for "!a".


More information about the Digitalmars-d mailing list