Compare two objects

grauzone none at example.net
Tue Feb 10 05:24:02 PST 2009


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


More information about the Digitalmars-d-learn mailing list