Search code examples
delphitypesvariantunsigned-integer

Erroneous conversion of Cardinal to OleVariant. UInt64 is ok


program UInt32ToVariant;

uses
  Vcl.Dialogs, System.SysUtils, System.Variants;

var
  ui32Val: Cardinal;
  si64Val: Int64;
  ui64Val: UInt64;
  v1: Variant;
  v2: OleVariant;
  sb: TStringBuilder;

begin
  sb := TStringBuilder.Create();
  try
    ui32Val := 4234687430;
    si64Val := Int64.MaxValue;
    ui64Val := UInt64.MaxValue;

    v1 := ui32Val;
    v2 := ui32Val;
    sb.AppendLine('Unsigned 32 bit integer:'#9 + Cardinal.ToString(ui32Val));
    sb.AppendLine(#9'to Variant:'#9 + VarToStr(v1));
    sb.AppendLine(#9'to OleVariant:'#9 + VarToStr(v2));
    sb.AppendLine();

    v1 := si64Val;
    v2 := si64Val;
    sb.AppendLine('Signed 64 bit integer:'#9 + Int64.ToString(si64Val));
    sb.AppendLine(#9'to Variant:'#9 + VarToStr(v1));
    sb.AppendLine(#9'to OleVariant:'#9 + VarToStr(v2));
    sb.AppendLine();

    v1 := ui64Val;
    v2 := ui64Val;
    sb.AppendLine('Unsigned 64 bit integer:'#9 + UInt64.ToString(ui64Val));
    sb.AppendLine(#9'to Variant:'#9 + VarToStr(v1));
    sb.AppendLine(#9'to OleVariant:'#9 + VarToStr(v2));

    ShowMessage(sb.ToString());
  finally
    sb.Free();
  end;
end.

The result is:

Unsigned 32 bit integer:    4234687430
    to Variant: 4234687430
    to OleVariant:  -60279866 (Wrong!)

Signed 64 bit integer:  9223372036854775807
    to Variant: 9223372036854775807
    to OleVariant:  9223372036854775807

Unsigned 64 bit integer:    18446744073709551615
    to Variant: 18446744073709551615
    to OleVariant:  18446744073709551615 (Correct again!)

Is it really a bug in Delphi or I am doing something wrong?

I could assume that OleVariant doesn't support unsigned integers at all, but unsigned 64 bit integer is supported, 32-bit not.


Solution

  • This is a Delphi bug.

    It was reported as RSP-18363 Incorrect Conversion Cardinal to OleVariant

    The bug description:

    Incorrect direct conversion of the Cardinal to OleVariant. The result differs from the transformation of the Cardinal into the Variant into the OleVariant