How compatible are static class methods and regular routine pointers?

心不动则不痛 提交于 2019-12-12 09:53:35

问题


It seems to me that static class methods and regular routine pointers are compatible from a practical viewpoint but the compiler doesn't know this. Example:

type
  TFunc = function(i: Integer): string;

  TMyClass = class
  public
    class function StaticMethod(i: Integer): string; static;
  end;

class function TMyClass.StaticMethod(i: Integer): string;
begin
  Result := '>' + IntToStr(i) + '<';
end;

function GlobalFunc(i: Integer): string;
begin
  Result := '{' + IntToStr(i) + '}';
end;

procedure CallIt(func: TFunc);
begin
  Writeln(func(42));
end;

begin
  CallIt(TMyClass.StaticMethod); //       1a: doesn't compile
  CallIt(GlobalFunc); //                  1b: compiles

  CallIt(@TMyClass.StaticMethod); //      2a: compiles iff $TYPEDADDRESS OFF
  CallIt(@GlobalFunc); //                 2b: compiles iff $TYPEDADDRESS OFF

  CallIt(Addr(TMyClass.StaticMethod)); // 3a: compiles
  CallIt(Addr(GlobalFunc)); //            3b: compiles

  Readln;
end.

As noted in the comments, 3a and 3b both compile (where compiles includes works at runtime in this simple example). 2a and 2b both compile if and only if $TYPEDADDRESS is OFF. But 1a/1b are different: 1b always compiles while 1a never compiles. Is this distinction by design? Is using 3a save or have I overlooked any pitfalls?


回答1:


There is no difference on binary level between static class function and ordinary function with the same arguments&result type - they are binary compatible, so your example is OK. Of course they are different types for the compiler, so you need Addr() or @ to compile your example.

Addr() is equivalent to the @ operator except that it is unaffected by the $T compiler directive.If you switch type check on your example will not compile:

{$T+}
begin
  CallIt(@TMyClass.StaticMethod);
  Readln;
end.

[Pascal Error] Project10.dpr(28): E2010 Incompatible types: 'TFunc' and 'Pointer'



来源:https://stackoverflow.com/questions/6940171/how-compatible-are-static-class-methods-and-regular-routine-pointers

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!