int opEquals(Object), and other legacy ints (!)

kris foo at bar.com
Sun Jul 30 17:18:13 PDT 2006


Bruno Medeiros wrote:
> Walter Bright wrote:
> 
>> Stewart Gordon wrote:
>>
>>> Walter Bright wrote:
>>>
>>>> Stewart Gordon wrote:
>>>>
>>>>> xs0 wrote:
>>>>> <snip>
>>>>>
>>>>>> Well, I'm just guessing, but I think something like
>>>>>>
>>>>>>  > int opEquals(Foo foo)
>>>>>>  > {
>>>>>>  >     return this.bar == foo.bar;
>>>>>>  > }
>>>>>>
>>>>>> is compiled to something like
>>>>>>
>>>>>>> return this.bar-foo.bar; // 1 instruction
>>>>>>
>>>>>>
>>>>>> but if the return type is bool, it becomes
>>>>>>
>>>>>>> return this.bar-foo.bar?1:0; // 3 instructions
>>>>>
>>>>>
>>>>> If it does this, then there's a serious bug in the compiler.
>>>>
>>>>
>>>> What instruction sequence do expect to be generated for it?
>>>
>>>
>>> If anything resembling the above, then
>>>
>>>     return this.bar-foo.bar?0:1;
>>
>>
>> ? Let's look at an example:
>>
>> class Foo
>> {
>>     int foo, bar;
>>
>>     int Eq1(Foo foo)
>>     {
>>         return this.bar-foo.bar?0:1;
>>     }
>>
>>     int Eq2(Foo foo)
>>     {
>>         return this.bar-foo.bar;
>>     }
>> }
>>
>> which generates:
>>
>>     Eq1:
>>                 mov     EDX,4[ESP]
>>                 mov     ECX,0Ch[EAX]
>>                 sub     ECX,0Ch[EDX]
>>                 cmp     ECX,1
>>                 sbb     EAX,EAX
>>                 neg     EAX
>>                 ret     4
>>     Eq2:
>>                 mov     ECX,4[ESP]
>>                 mov     EAX,0Ch[EAX]
>>                 sub     EAX,0Ch[ECX]
>>                 ret     4
>>
>> So we have 4 instructions generated rather than 1. If there's a trick 
>> to generate only one instruction for Eq1, I'd like to know about it.
>>
>>>> I can. (a == b), where a and b are ints, can be implemented as (a - 
>>>> b), and the result is int 0 for equality, int !=0 for inequality.
>>>
>>>
>>> How is this (a == b) rather than (a != b)?
>>
>>
>> I don't understand your question.
> 
> 
> As per the other posts, Eq2 actually takes 2 instructions:
> 
> Eq2:
>     ...
>     sub     EAX,0Ch[ECX]
>     not    EAX;
> 
> 
> And uuuh.., I've checked gcc's generated code for a C++'s Eq1, and it 
> was only 2 instructions too, CMP and SETE ! :
> 
> Eq1:
>     ...
>     cmp     EAX,0Ch[ECX]
>     sete    EAX;
> 
> (http://www.cs.tut.fi/~siponen/upros/intel/instr/sete_setz.html)
> It seems to me perfectly valid, is there any problem here?


Yes indeed. Well spotted! On anything supporting the 386 instruction set 
(and D is targeted for 32-bit devices only), there's really no 
performance advantage in returning an int over returning a bool.

This should be addressed, so that some of the core APIs can be cleaned 
up appropriately?


> 
> What does the original Eq1 even do? :
> 
>     sub     ECX,0Ch[EDX]
>     cmp     ECX,1       // Huh?
>     sbb     EAX,EAX
>     neg     EAX
> 
> 

That's old-skool, pre-386 hacking :)



More information about the Digitalmars-d-bugs mailing list