www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - object.opEquals return type

reply Edward Diener <eddielee_no_spam_here tropicsoft.com> writes:
Why is the return type of object.opEquals an 'int' rather than a 'bool' ?
Feb 24 2008
next sibling parent reply "Janice Caron" <caron800 googlemail.com> writes:
On 24/02/2008, Edward Diener <eddielee_no_spam_here tropicsoft.com> wrote:
 Why is the return type of object.opEquals an 'int' rather than a 'bool' ?

I haven't the faintest idea. However, I have submitted to bugzilla that the signature of opEquals (and opCmp, toString, etc.) should be fixed for const correctness. Perhaps the return type could be changed to bool in the same move? As in const bool opEquals(const(Object) o)
Feb 24 2008
next sibling parent reply Lars Ivar Igesund <larsivar igesund.net> writes:
Janice Caron wrote:

 On 24/02/2008, Edward Diener <eddielee_no_spam_here tropicsoft.com> wrote:
 Why is the return type of object.opEquals an 'int' rather than a 'bool' ?

I haven't the faintest idea. However, I have submitted to bugzilla that the signature of opEquals (and opCmp, toString, etc.) should be fixed for const correctness. Perhaps the return type could be changed to bool in the same move? As in const bool opEquals(const(Object) o)

Walter belive that an int is more efficient. In a long thread a year or two ago, it was shown that this is not the case, but Walter did not provide further comments. I even think that the int return can cause severe problems for templated solutions where opEquals is in use. We tried to fix this in Tango, but apparently the int is hardcoded in the compiler. -- Lars Ivar Igesund blog at http://larsivi.net DSource, #d.tango & #D: larsivi Dancing the Tango
Feb 24 2008
parent Edward Diener <eddielee_no_spam_here tropicsoft.com> writes:
Janice Caron wrote:
 On 24/02/2008, Lars Ivar Igesund <larsivar igesund.net> wrote:
 Walter belive that an int is more efficient.

The way I see it, the problem is that bool has a defined width. It shouldn't have, because bool is special. One possible solution would be to have explicit types bool8 and bool32, with "bool" meaning "either bool8 or bool32, at the compiler's discretion". The compiler would only need very simple rules to choose which to use (e.g. if function parameter or function return or local variable, use bool32, else use bool8), and allow either to implicitly and losslessly cast to the other. I think that would work. It would allow the programmer's intent to be specified in the code, but preserve efficiency at all levels.

Having more than one bool type complicates the situation for no good reason. A bool is conceptually a 'true' or 'false' value, so it hardly needs two types to handle that simple idea. I know you are saying that having two types would enable the compiler to choose the most efficient, but a compiler should be able to do this internally anyway without creating the complication. If the reason given by Walter for having OpEquals retur an 'int' instead of a 'bool' is efficiency, than a 'bool' should internally be an 'int', else that same reason can be given for any operation potentially involving only a true or false value. Otherwise a 'bool' should internally remain a 'byte' and efficiency should be much less of a consideration than correct conceptual design. Hopefully Walter will realize his delusion and correct his mistake.
Feb 24 2008
prev sibling parent Edward Diener <eddielee_no_spam_here tropicsoft.com> writes:
Janice Caron wrote:
 On 24/02/2008, Edward Diener <eddielee_no_spam_here tropicsoft.com> wrote:
 Why is the return type of object.opEquals an 'int' rather than a 'bool' ?

I haven't the faintest idea. However, I have submitted to bugzilla that the signature of opEquals (and opCmp, toString, etc.) should be fixed for const correctness. Perhaps the return type could be changed to bool in the same move? As in const bool opEquals(const(Object) o)

I fully agree that you have it correct above.
Feb 24 2008
prev sibling next sibling parent reply Max Samukha <maxsamukha gmail.com> writes:
Edward Diener wrote:

 Why is the return type of object.opEquals an 'int' rather than a 'bool' ?

Performance is supposed to be better with ints. It was discussed here: http://www.digitalmars.com/d/archives/digitalmars/D/bugs/7933.html#N7933
Feb 24 2008
next sibling parent reply Edward Diener <eddielee_no_spam_here tropicsoft.com> writes:
Max Samukha wrote:
 Edward Diener wrote:
 
 Why is the return type of object.opEquals an 'int' rather than a 'bool' ?

Performance is supposed to be better with ints. It was discussed here: http://www.digitalmars.com/d/archives/digitalmars/D/bugs/7933.html#N7933

Thanks for the link. It is very poor logic to justify an incorrect design decision merely based on efficiency, and I am surprised that Walter did so. One might as well eliminate 'bool' entirely from the language based on the same supposition of inefficiency as compared to an 'int'. If one were to carry the efficiency argument further, than the other possible logical conclusion is that a 'bool' should be an 'int' ( constrained to be of value either 0 or 1 ) rather than a 'byte'. But to justify a poor design decision based purely on efficiency is exceedingly silly. Hopefully Walter will come to his senses and change the decsion to return 'int' from object.opEquals.
Feb 24 2008
parent reply JMNorris <nospam nospam.com> writes:
Edward Diener <eddielee_no_spam_here tropicsoft.com> wrote in
news:fps7es$1uh4$1 digitalmars.com: 

 If one were to carry the efficiency argument further, than the other 
 possible logical conclusion is that a 'bool' should be an 'int' ( 
 constrained to be of value either 0 or 1 ) rather than a 'byte'. But
 to justify a poor design decision based purely on efficiency is
 exceedingly silly.

If I understood the discusion in the previous link correctly, it was (at least mostly) the constraint to 0 or 1, not the smaller size of the return, that was less efficient. Returning an int may still be silly (the mere existance of this thread suggests that it is at least confusing), but making a bool the size of an int won't solve the efficiency concern. -- JMNorris
Feb 26 2008
parent reply Dan <murpsoft hotmail.com> writes:
JMNorris Wrote:

 Edward Diener <eddielee_no_spam_here tropicsoft.com> wrote in
 news:fps7es$1uh4$1 digitalmars.com: 
 
 If one were to carry the efficiency argument further, than the other 
 possible logical conclusion is that a 'bool' should be an 'int' ( 
 constrained to be of value either 0 or 1 ) rather than a 'byte'. But
 to justify a poor design decision based purely on efficiency is
 exceedingly silly.

If I understood the discusion in the previous link correctly, it was (at least mostly) the constraint to 0 or 1, not the smaller size of the return, that was less efficient. Returning an int may still be silly (the mere existance of this thread suggests that it is at least confusing), but making a bool the size of an int won't solve the efficiency concern. -- JMNorris

FYI making a bool a bit is not efficient in memory or time. The code produced ends up having to "and 0x0000_0001" in order to mask the bit value; which takes 5 bytes on top of the value and the mov instruction. Making a bool a byte may or may not be efficient in time and space complexity, depending on how it gets used. The x86 normal 4-byte register instructions were the most optimized for, and in most cases a byte form can be used but it takes an extra byte to tell the CPU to use the byte operand. There are two or three particularly useful byte-operand instructions. In my opinion it would be a considerable waste to set up boolean as a byte just to use these. Most compilers ignore them, and I tend to agree with that. However, if you ever hand code assembler they're quite useful. Regards, Dan
Feb 26 2008
parent reply Frank Benoit <keinfarbton googlemail.com> writes:
Putting the int/bool performance difference in relation to the whole thing:
Calling opEquals makes a virtual function call. Then at least the given 
object reference is compared once against this. For a useful opEquals 
much more can happen, eg. a dynamic cast...
Now, is it still a _relevant_ performance hit (if any), to use bool 
instead of int here?
Feb 26 2008
parent Dan <murpsoft hotmail.com> writes:
Frank Benoit Wrote:

 
 Putting the int/bool performance difference in relation to the whole thing:
 Calling opEquals makes a virtual function call. Then at least the given 
 object reference is compared once against this. For a useful opEquals 
 much more can happen, eg. a dynamic cast...
 Now, is it still a _relevant_ performance hit (if any), to use bool 
 instead of int here?
 

I never thought it was. Too many people think "oh, it's inefficient to use more than a bit" but fail to recognize that x86 machine code has a finite discrete set of instructions which operate on finite discrete operand sizes. It really was time to set up a new platform decades ago - too bad Intel tanked the Itanic. Regards, Dan
Feb 27 2008
prev sibling parent Sean Kelly <sean invisibleduck.org> writes:
== Quote from Max Samukha (maxsamukha gmail.com)'s article
 Edward Diener wrote:
 Why is the return type of object.opEquals an 'int' rather than a 'bool' ?

http://www.digitalmars.com/d/archives/digitalmars/D/bugs/7933.html#N7933

It was shown later in that same thread that there is no performance penalty for returning a bool. The response is somewhat buried and it took me a while to find it last time I looked. However, Walter indicated that he was unaware of the ASM instruction that allows for this improvement and so the back-end used by DMD does something else instead which is much slower. Sean
Feb 26 2008
prev sibling next sibling parent "Janice Caron" <caron800 googlemail.com> writes:
On 24/02/2008, Lars Ivar Igesund <larsivar igesund.net> wrote:
 Walter belive that an int is more efficient.

The way I see it, the problem is that bool has a defined width. It shouldn't have, because bool is special. One possible solution would be to have explicit types bool8 and bool32, with "bool" meaning "either bool8 or bool32, at the compiler's discretion". The compiler would only need very simple rules to choose which to use (e.g. if function parameter or function return or local variable, use bool32, else use bool8), and allow either to implicitly and losslessly cast to the other. I think that would work. It would allow the programmer's intent to be specified in the code, but preserve efficiency at all levels.
Feb 24 2008
prev sibling parent "Janice Caron" <caron800 googlemail.com> writes:
On 24/02/2008, Edward Diener <eddielee_no_spam_here tropicsoft.com> wrote:
  I know you are saying that
  having two types would enable the compiler to choose the most efficient,
  but a compiler should be able to do this internally anyway without
  creating the complication.

Right. I didn't mean to imply that bool8 or boo32 should necessarily be exposed to the user (...although doing so would be harmless...). The whole point is that the user would just write "bool" and the compiler would does what was right for that situation. So struct S { bool b; /* b is a bool8 */ } bool f() /* f returns a bool32 */ S s; s.b = f(); /* implicit cast happens */ As far as I can see, everything just works, efficiency is maintained, and the programmer's intent is clear at all times. I do agree with you that if Walter goes for this, bool8 and bool32 should be internal concepts, not normally exposed to the user.
Feb 24 2008