Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 596
Matej Avatar asked Aug 06 '19 13:08

Matej


People also ask

How do you fix an ambiguous call to overloaded function?

There are two ways to resolve this ambiguity: Typecast char to float. Remove either one of the ambiguity generating functions float or double and add overloaded function with an int type parameter.

When you call an overloaded function how compiler identified?

At compile time, the compiler chooses which overload to use based on the types and number of arguments passed in by the caller. If you call print(42.0) , then the void print(double d) function is invoked. If you call print("hello world") , then the void print(std::string) overload is invoked.

What happens when you overload functions?

Function overloading is a feature of object-oriented programming where two or more functions can have the same name but different parameters. When a function name is overloaded with different jobs it is called Function Overloading.

How function calls are matched with overloaded functions?

The process of matching function calls to a specific overloaded function is called overload resolution. Just because there is no exact match here doesn't mean a match can't be found -- after all, a char or long can be implicitly type converted to an int or a double .


1 Answers

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;
like image 195
Andreas Rejbrand Avatar answered Sep 27 '22 17:09

Andreas Rejbrand