Consider this program:
{$APPTYPE CONSOLE}
uses
System.SysUtils;
procedure Foo;
begin
end;
type
TProcedure = procedure;
const
FooConst: TProcedure =
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 .
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:
addr()
rather than the @
operator.@FooVar
or @FooConst
to Pointer
, e.g. Pointer(@FooVar)
.