【问题标题】:Compiler bug with overloaded function具有重载函数的编译器错误
【发布时间】:2019-08-06 13:38:32
【问题描述】:

以下代码给出了堆栈溢出:

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;

Integer 重载函数永远不会被调用,Double 重载函数会调用自身直到堆栈溢出。

以下代码按预期工作:

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;

这是编译器错误还是预期行为?

【问题讨论】:

    标签: delphi delphi-xe5 overload-resolution


    【解决方案1】:

    我怀疑这是意料之中的。

    问题在于编译器固有的 Round 函数返回一个 64 位整数。 CodeInsight 和the official documentation 都告诉我这一点。如果编译器必须在采用 32 位整数或双精度的例程之间进行选择,则当给定 64 位整数时,它会选择接受双精度的例程。

    要验证这一点,请尝试

    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;
    

    【讨论】:

      【解决方案2】:

      System.Round 函数产生 Int64 值。

      我认为编译器保留了Func 函数的Double 重载比Integer 重载更合适。

      事实上,Integer 重载可能会导致信息丢失,如果参数的值超过Integer 的类型 min-max(从 -2147483648 到 2147483647,请参见 System.Integer)。

      Integer 参数更改为Int64 参数将解决问题并避免信息丢失。

      function Func(x : Double) : Double; overload;
      function Func(x : Int64) : Double; overload;
      
      ...
      
      function Func(x : Double) : Double;
      begin
        Result := Func(Round(x));
      end;
      
      function Func(x : Int64) : Double;
      begin
        Result := 1.0;
      end;
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-03-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多