8

The way adding strings and variants behaves in Delphi (10.2 Tokyo) was a complete surprise to me. Can someone provide a reasonable explanation for this "feature" or shall we call it a bug ?

function unexpected: string;
var v: Variant;
begin
  result := '3';
  v := 2;
  result := v + result;
  ShowMessage(result);  //displays 5, I expected 23

  result := '3';
  v := 2;
  result := result + '-' + v;
  ShowMessage(result)   //displays -1, I expected 3-2
end;
Peter
  • 123
  • 1
  • 8
  • 1
    Explicitly setting `VarAsType(v,varUString)` would bring your results as expected. – LU RD Aug 15 '18 at 12:37
  • yes I know, or using VarToStr(), but the point was I also expected compiler to convert any variant references to string in the above expression. thanks to hnd I now know better – Peter Aug 15 '18 at 13:51

1 Answers1

10

result := v + result

Delphi's Variant type is a slightly extended version of the Win32 API's VARIANT type and supposed to be compatible with it so long as you do not use any Delphi-specific types. Additionally, when you use Delphi-specific string types, it is supposed to behave like it would with the OLE string type. In the Win32 API, it is specifically documented that adding a string and a number will result in a (numeric) addition, not a string concatenation, that you need to have two string operands to get a string concatenation:

VarAdd:

Condition                                          Result
Both expressions are strings                       Concatenated
[...]
One expression is numeric and the other a string   Addition
[...]

I suspect VarAdd is defined like that to make things easier for VB users.

result := result + '-' + v

Here result + '-' should perform string concatenation since both operands are strings. '3-' + v is then treated as a numeric addition, requiring 3- to be parsed as a number. I believe that since there are contexts in which the sign follows the digits, this parse succeeds and produces -3. Adding 2 to that results in -1.

  • 1
    Ultimately it is down to the API. The matrix in "variants.SimpleVarOp" dictates that a sting ('3-') concatenated with an integer (2) should produce a double and calls "oleaut32.VarR8FromStr" for '3-' using the user default locale, which converts the string to -3. – Sertac Akyuz Aug 15 '18 at 14:01