Why does Format reject procedure address arguments starting with XE4

前端 未结 2 1004
一生所求
一生所求 2020-12-20 20:26

Consider this program:

{$APPTYPE CONSOLE}

uses
  System.SysUtils;

procedure Foo;
begin
end;

type
  TProcedure = procedure;

const
  FooConst: TProcedure =         


        
相关标签:
2条回答
  • 2020-12-20 21:05

    I think that the behaviour of the new compiler XE7 is more consistent with the specification and the error need to be shown in this case, since the {$TYPEDADDRESS ON} enforce the @ operator to return a typed pointer and the Format function instead gets as input an untyped generic pointer.

    Since the the purpose of the {$TYPEDADDRESS ON} is encouraging careful use of pointers, catching at compile time unsafe pointer assignments, it is right that if the function expects a generic untyped pointer(and in this case make sense because the function purpose is to print the address of it - so no need to have typed pointer to retrieve its address), the compiler will catch an error in the case of a typed pointer is passed, the behaviour is consistent with the specification.

    I think that in this case the right way to go(based on the documentation) would be :

      Writeln(Format('%p', [Addr(FooConst)]));
      Writeln(Format('%p', [Addr(FooVar)]));
    

    since the Addr function always returns an untyped Pointer that is what the Format with %p expects and needs.

    What I assume is that in previous versions the compiler, in a case like this one, used to perform an automatic cast : Pointer(@FooConst) , but it doesn't make too much sense because of the {$TYPEDADDRESS ON} directive .

    0 讨论(0)
  • 2020-12-20 21:14

    I believe that this is a compiler bug and have submitted a QC report: QC#127814.

    As a work around you can use either of the following:

    1. Use addr() rather than the @ operator.
    2. Cast @FooVar or @FooConst to Pointer, e.g. Pointer(@FooVar).
    0 讨论(0)
提交回复
热议问题