On 5/18/18 9:48 PM, Jonathan M Davis wrote:
On Saturday, May 19, 2018 01:27:59 Neia Neutuladh via Digitalmars-d-learn
wrote:
On Friday, 18 May 2018 at 23:53:12 UTC, IntegratedDimensions
wrote:
Why does D complain when using == to compare with null? Is
there really any technical reason? if one just defines == null
to is null then there should be no problem. It seems like a
pedantic move by who ever implemented it and I'm hoping there
is actually a good technical reason for it.
tldr: this error is outdated.
In the days of yore, "obj == null" would call
"obj.opEquals(null)". Attempting to call a virtual method on a
null object is a quick path to a segmentation fault. So "obj ==
null" would either yield false or crash your program.
I remember this, and I remember arguing for the current behavior many
times (after having many many crashes) :)
https://forum.dlang.org/post/fqlgah$15v2$1...@digitalmars.com
Read that thread if you want to see the rationale.
However, I'd argue it's still good to keep the error as there is
literally no point to not using == null on class references vs. is null.
You now would get the same result, but it's faster/cleaner.
Actually, that runtime function has existed since before TDPL came out in
2010. It even shows the implementation of the free function opEquals (which
at the time was in object_.d rather than object.d). I'm not even sure that
the error message was added before the free function version of opEquals
was. Maybe when that error message was first introduced, it avoided a
segfault, but if so, it has been a _long_ time since that was the case.
Some things in TDPL were forward-thinking. I remember Andrei fleshing
out some of how the languages SHOULD behave in the forums or mailing
lists for the purposes of writing TDPL even though it didn't yet behave
that way. In fact, I'm almost positive the new object comparison
function came as a result of TDPL (but I'm not 100% sure). Some of TDPL
still has never been implemented.
Long story short, don't date the existence of features in TDPL based on
the publication :)
In this case, for fun (what is wrong with me), I looked up the exact
date it got added, and it was Feb 2010:
https://github.com/dlang/druntime/commit/2dac6aa262309e75ad9b524cb4d1c3c1f0ecc2ae.
TDPL came out in June 2010, so this feature does predate TDPL by a bit.
In fact, through this exercise, I just noticed that the reason it
returns auto instead of bool is to make sure it gets into the now
defunct "generated" object.di file
(https://github.com/dlang/druntime/pull/2190).
It *is* faster to call "foo is null" than "foo == null", but I
don't think that's particularly worth a compiler error. The
compiler could just convert it to "is null" automatically in that
case.
It's not worth a compiler error if we didn't already have it, but I
don't know that it's worth taking out. It's really what you should be
doing, it's just that the penalty for not doing it isn't as severe as it
used to be.
One casualty of the current state of affairs is that no object
may compare equal to null.
And let's keep it that way!
Of
course, the most notable case where using == with null is a terrible idea is
dynamic arrays, and that's the case where the compiler _doesn't_ complain.
I use arr == null all the time. I'm perfectly fine with that, and
understand what it means.
Using == with null and arrays is always unclear about the programmer's
intent and almost certainly wasn't what the programmer intended.
I beg to differ.
If the
programmer cares about null, they should use is. If they care about lengnth,
then that's what they should check. Checking null with == is just a huge
code smell.
IMO, doing anything based on the pointer of an array being null is a
huge code smell. In which case, == null is perfectly acceptable. I'm
comparing my array to an empty array. What is confusing about that?
I actually hate using the pointer in any aspect -- an array is
semantically equivalent to its elements, it's not important where it's
allocated. The only place D forces me to care about the pointer is when
I'm dealing with ranges.
So, perhaps the compiler is being pedantic, but it's still telling you the
right thing. It's just insisting about it in the case where it matters less
while not complaining aobut it in the case where it really matters, which is
dumb. So IMHO, if anything, adding an error message for the array case would
make more sense than getting rid of the error with pointers and references.
I hope this never happens.
-Steve