"==" not symmetric
Lionello Lunesu
lio at lunesu.remove.com
Wed May 24 00:07:44 PDT 2006
Going thirty and I'm still mixing left and right :S
You've made some good points. Indeed, since opEquals has to check the
type of the passed Object, it'll automatically check for null too.
Still odd though, that you can get a different result when you do o1==o2
or o2==o1, but I guess the library programmer should take care of that :)
L.
Unknown W. Brackets wrote:
> Bad means a pointer to an invalid object. A bad pointer. I was trying
> to cover all the bases.
>
> Your typical opEquals looks like this:
>
> bool opEquals(Object o)
> {
> Foo f = cast(Foo) o;
>
> // If o was null, or if f is now null (doesn't match class) fail.
> if (f is null)
> return false;
>
> return f.prop == this.prop;
> }
>
> Anything else either doesn't work properly with subclassing, isn't
> typesafe, or will segfault. This doesn't seem wrong to me.
>
> Okay, missed that x and y were supposed to be objects. You seem to be
> missing a "x y" case, then. This would be the same as "y x", though.
>
> It would be a bad idea to check the class info imho. Why can't a XYZ
> equal an ABC even if they share no parents aside from Object? But that
> does mean the order of the comparison does matter (consider Array ==
> SpecializedArray vs. SpecializedArray == Array.)
>
> No, opEquals should never begin with any check on lhs... lhs will be
> this. It should however check rhs, first casting it more than likely,
> and then checking for null on the cast.... since, if the cast fails, it
> will be null.
>
> This same check cannot be necesarily made in ==, since it can't know
> what other classes the opEquals supports.
>
> Still, checking for null could be a good thing for sanity; I'd guess it
> doesn't because opEquals would have to anyway.
>
> -[Unknown]
>
>
>> 'bad'? I don't think you can tell whether a pointer is bad or valid. I
>> think calling opEquals(null) is bad, since it's likely to crash. And
>> I've noticed before that many implementations start with a if(lhs is
>> null) check. It just makes sense to put that check 1 function up in
>> the code, namely in the ==.
>>
>>> I don't know what "y" is on your table.
>>
>> 'y' is just different from 'x' :)
>>
>>
>> Might not be a bad idea to also check the classinfo of both objects in
>> the == ?
>>
>>> So, okay... the only differences we have:
>>>
>>> If o1 is null, reversing the comparison will depend on opEquals
>>> returning false when it is passed a null pointer (which should be the
>>> case.)
>>
>> Right. At the moment opEquals _must_ begin with "if (lhs is null)
>> return false;", but this can easily be enforced by putting the same
>> check in ==.
>>
>>> Comparing a valid pointer to a bad pointer cannot be properly
>>> reversed, or it might cause a segfault. This is always wrong anyway
>>> imho.
>>
>> Right. Nothing you can do about that I'm afraid.
>>
>>> That said, opEquals (imho) will either always check for null or
>>> cannot be reversed (null == evaluatesToNullObject is always false.)
>>> So it would seem logical to do something like you suggested.
>>
>> It would seem so :)
More information about the Digitalmars-d
mailing list