Search code examples
delphidelphi-xe5overload-resolution

Compiler bug with overloaded function


The following code gives a stack overflow:

function Func(x : Double) : Double; overload;
function Func(x : Integer) : Double; overload;


function Func(x : Double) : Double;
begin
  Result := Func(Round(x));
end;


function Func(x : Integer) : Double;
begin
  Result := 1.0;
end;

The Integer overloaded function is never called, the Double overloaded function calls itself until the stack overflows.

The following code works as expected:

function Func2(x : Double) : Double; overload;
function Func2(x : Integer) : Double; overload;

function Func2(x : Double) : Double;
var
  ix : Integer;
begin
  ix := Round(x);
  Result := Func(ix);
end;


function Func2(x : Integer) : Double;
begin
  Result := 1.0;
end;

Is this a compiler bug or expected behavior?


Solution

  • This is, I suspect, to be expected.

    The issue is that the compiler-intrinsic Round function returns a 64-bit integer. Both CodeInsight and the official documentation tells me that. And if the compiler has to chose between a routine taking a 32-bit integer or a double, when given a 64-bit integer, it chooses the routine accepting a double.

    To verify this, try

    procedure Test(x: Double); overload;
    begin
      ShowMessage('double');
    end;
    
    procedure Test(x: Integer); overload;
    begin
      ShowMessage('integer');
    end;
    
    procedure TForm5.FormCreate(Sender: TObject);
    begin
      Test(Int64.MaxValue)
    end;