Qian Xu wrote:
Hi All,
I want to test, if two objects are equal.
The rules are as follows:
1. When both are null, it should return true.
2. When one of them is null, it should return false.
3. When both not null, then compare their values (as two strings)
My test code
---------------------------------------------------------------
class Test {
private int value;
this(int value) {
this.value = value;
}
public int getValue() {
return this.value;
}
bool opEquals(Test obj) {
if (obj is null) {
return this is null;
}
return this.getValue() == obj.getValue();
}
}
procedure test(Test a, Test b) {
if (a is null && b is null) return true;
if (a !is null && a == b) return true;
return false;
}
void main()
{
Test a;
Test b = new Test(100);
assert(test(a, b)); // ok
assert(a != b); // av error
}
----------------------------------------------------------------
If object at the left side of the != is null, I will get an AV error
immediately.
If I want to compare two objects safely, I have to write my own test(..)
function.
But this is not nice.
Can someone explain, is this a design shortcoming of D-Compiler, or I am
wrong.
It's a shortcoming in the design of the == operator. Code like "a==b"
will always be compiled to this:
> a.opEquals(b)
If a is null, the call will always cause a segfault. You simply can't
call a method on a null object. There are two reasons for this: 1. it
will dereference the object's vtable to look up virtual methods and 2.
the runtime will try to call the object's invariant, which segfaults
too. (Actually, I see an assert with a null check in _d_invariant(). But
somehow, gdb usually still shows a segfault in _d_invariant(). Maybe
Phobos isn't compiled in debug mode.)
The D compiler even has a special rule to disallow compilation of code
like "a==null" (yes, because of the null literal). It seems Walter added
this, because people were using this code to check if an object is null.
Conclusion: == is absolutely useless in your case. Use something else.
Best regards
--Qian Xu