[fpc-devel] How FPC handles dynamic arrays with const modifier?

Jonas Maebe jonas.maebe at elis.ugent.be
Mon Aug 12 23:41:52 CEST 2013


On 12 Aug 2013, at 23:32, Maciej Izak wrote:

> Hi, I have some code (very important for next version of
> Generics.Collections):
> 
> ------ code ------
> {$IFDEF FPC}{$MODE DELPHI}{$ENDIF}
> {$APPTYPE CONSOLE}
> 
> uses
>  Types;
> 
> {$IFDEF FPC}
> function DynArraySize(p : pointer): tdynarrayindex; external name
> 'FPC_DYNARRAY_LENGTH';
> {$ENDIF}
> 
> procedure Foo(A: Pointer);
> begin
>  WriteLn(DynArraySize(A));
> end;
> 
> type
>  TFoo = procedure(const A: TIntegerDynArray);
> 
> var
>  Test: TFoo;
> begin
>  Test := @Foo;
>  Test(TIntegerDynArray.Create(1, 2, 3, 4));
>  ReadLn;
> end.
> ------ code ------
> 
> In Delphi all is ok (DynArraySize in Foo returns 4). In FPC DynArraySize
> return 1 (and program crash at the end). Is dynamic array with const
> modifier in FPC passed by value?

It is undefined how it is passed (and how it is passed can change from version to version, although we will never change such details just because we can). Relying on such implementation details is wrong, regardless of what Delphi does. We do not aim to create a code generator that creates exactly the same code as Delphi, we only work towards compatibility at the Pascal language level (that does not include pointer hacks to peek at implementation details) and only to the extent that this Pascal-level behaviour is documented.

> With small modifications especially for
> FPC (by adding constref) all works fine:
> 
> ------ code ------
> procedure Foo(constref A: Pointer);
> begin
>  WriteLn(DynArraySize(A));
> end;
> 
> type
>  TFoo = procedure(constref A: TIntegerDynArray);
> ------ code ------
> 
> I can live with constref, but I'm much worried by this behavior (in version
> without constref). Why my code don't work in both compilers same? I would
> like to understand...

The behaviour of "const" is implementation-defined in FPC. There is no guarantee regarding how it affects parameter passing at the low level for non-cdecl/cppdecl/mwpascal calling conventions.


Jonas


More information about the fpc-devel mailing list