That's not so much a Delphi WAT as a COM one. VB (up to 6, and VBA) also interpreted True as -1. To be fair, it does make a kind of sense to have all the bits of True have the opposite value to the ones in False... In the case of Delphi, it's surprising since Ord(True) = 1. Then again, it's the kind of confusion you get when assigning different types of Variants to each other... (Why would you want to add two booleans, and what would you expect the result to be?)
It does use _VarToDouble() in RealOp() but in that the Boolean->Integer is still done (for V.VType=varBoolean) with -1 as a result, which in turn is put into a double for addition. So even with the fact it does double addition... it has converted to integer first.
Although this might be considered a bug according to the documentation: var v1: Variant; r1: Real; begin v1 := True; r1 := v1; Results in r1 = -1 while the documentation says it should be 1. ("Boolean -> Real: False = 0, True = 1")
Jennifer Powell yes, but if you look at the conversion table in that documentation I mentioned it clearly stated that converting from boolean to real via variant it should be 1. While -1 from boolean to integer. So the documentation is clearly wrong. That conversion table is not for conventional conversion but especially for variants! It says "Variant type conversion rules". So, a bug in the documentation.
Oh OK, I see. Well, they made a typo in the docs - nothing new there of course. It is fair to say it's better to have bugs in the docs than in the code generator!
As David Heffernan wrote, this is a COM type, and the boolean for COM is a WordBool and not a pascal/Delphi boolean, with 0 or $ffff as values (not $ff Jennifer Powell) so the result is as expected.
And what did you expect? According to the documentation a boolean conversion to integer (via variant) is False = 0, True = all bits set to 1 (-1 if Integer, 255 if Byte, etc.) docwiki.embarcadero.com - Variant Types (Delphi) - RAD Studio
ReplyDeleteThat's not so much a Delphi WAT as a COM one. VB (up to 6, and VBA) also interpreted True as -1.
ReplyDeleteTo be fair, it does make a kind of sense to have all the bits of True have the opposite value to the ones in False... In the case of Delphi, it's surprising since Ord(True) = 1.
Then again, it's the kind of confusion you get when assigning different types of Variants to each other... (Why would you want to add two booleans, and what would you expect the result to be?)
The variant type was originally just a wrapper for OLE variants, and a boolean in OLE Automation is a two byte value where false = -1.
ReplyDeleteMartijn Coppoolse Well it wouldn't be unreasonable to expect + to act as OR (and * to act as AND)... but yea variants are kinda weird critters.
ReplyDeleteTBH the real WAT comes when you step through the code because it then goes through some float conversion when doing the addition.
ReplyDeleteYet another reason to stay away from Variants as much as possible.
ReplyDeleteIt does use _VarToDouble() in RealOp() but in that the Boolean->Integer is still done (for V.VType=varBoolean) with -1 as a result, which in turn is put into a double for addition. So even with the fact it does double addition... it has converted to integer first.
ReplyDeleteAlthough this might be considered a bug according to the documentation:
ReplyDeletevar
v1: Variant;
r1: Real;
begin
v1 := True;
r1 := v1;
Results in r1 = -1 while the documentation says it should be 1. ("Boolean -> Real: False = 0, True = 1")
Rik van Kekem it wouldn't be the first time that documentation is wrong.
ReplyDeleteIt's not a bug.
ReplyDeleteWhat you see in the documentation is the conventional logic states for true/false for the "pascal type boolean," not as a boolean variant.
So,
showmessage(inttostr(ord(true)));
and
V1:=true;
showmessage(V1); // this works
will display 1 and -1.
So what's the deal? The Microsoft OLE boolean for true is $FF, not 1. Thus to be compatible with COM objects the variant boolean for true must be $FF.
This is old school stuff, going back more than 20 years with Delphi.
Jennifer Powell yes, but if you look at the conversion table in that documentation I mentioned it clearly stated that converting from boolean to real via variant it should be 1. While -1 from boolean to integer. So the documentation is clearly wrong. That conversion table is not for conventional conversion but especially for variants! It says "Variant type conversion rules". So, a bug in the documentation.
ReplyDeleteOh OK, I see. Well, they made a typo in the docs - nothing new there of course. It is fair to say it's better to have bugs in the docs than in the code generator!
ReplyDeleteRik van Kekem Delphi docs aren't very relevant here, this is a COM type
ReplyDeleteAs David Heffernan wrote, this is a COM type, and the boolean for COM is a WordBool and not a pascal/Delphi boolean, with 0 or $ffff as values (not $ff Jennifer Powell) so the result is as expected.
ReplyDelete