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?
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.
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.
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.
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 .
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;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With