[fpc-pascal] Argument evaluation order in Free Pascal and Delphi

Sven Barth pascaldragon at googlemail.com
Thu Oct 31 10:47:29 CET 2013


Am 31.10.2013 09:45, schrieb Michael Schnell:
> On 10/28/2013 02:47 PM, Dmitry Pribysh wrote:
>> As it is written in Free Pascal wiki 
>> <http://wiki.freepascal.org/Code_Conversion_Guide#Order_of_parameter_evaluation>, 
>> order of parameter evaluation is not defined in FPC, but it is 
>> defined in Delphi (Delphi guarantees left-to-right evaluation order).
>>
> IMHO =in fact evaluation of a parameter should not be guaranteed at all.
>
> The compiler should be free to inline a function, detect that the 
> parameter is not necessary for the evaluation of the function result 
> and drop the evaluation of the parameter (maybe giving a warning or 
> error message if that might trigger side-effects).
1. FPC does not guarantee evaluation order exactly for this reason
2. The compiler already does this inlining already in that way (at least 
partially).
Take this code:

=== code begin ===

program tinlinetest;

{$mode objfpc}

function GetStr1: String; inline;
begin
   Result := 'Hello World';
end;

function GetStr2: String;
begin
   Result := 'Hello World';
end;

function Test(aArg1: Integer; aArg2: String): Integer; inline;
begin
   Result := aArg1 * 42;
end;

begin
   Writeln(Test(42, 'Hello World'));
   Writeln(Test(42, GetStr1));
   Writeln(Test(42, GetStr2));
end.

=== code end ===

this will produce this output in the main function (2.7.1 and compiled 
with -O2):

=== assembler begin ===

PASCALMAIN:
.globl    _main
_main:
# Temps allocated between esp+0 and esp+512
# [20] begin
     pushl    %ebx
     addl    $-512,%esp
     call    FPC_INITIALIZEUNITS
# [21] Writeln(Test(42, 'Hello World'));
   // No usage of 'Hello World' constant here
     call    fpc_get_output
     movl    %eax,%ebx
     movl    %ebx,%edx
     movl    $1764,%ecx
     movl    $0,%eax
     call    fpc_write_text_sint
     call    FPC_IOCHECK
     movl    %ebx,%eax
     call    fpc_writeln_end
     call    FPC_IOCHECK
# [22] Writeln(Test(42, GetStr1));
   // here this might be a bug... the compiler inlines GetStr1, but does 
not detect that its result is constant and not used...
     call    fpc_get_output
     movl    %eax,%ebx
     movl    $_$TINLINETEST$_Ld1,%ecx
     leal    256(%esp),%eax
     movl    $255,%edx
     call    fpc_shortstr_to_shortstr
     leal    256(%esp),%ecx
     movl    %esp,%eax
     movl    $255,%edx
     call    fpc_shortstr_to_shortstr
     movl    $1764,%ecx
     movl    %ebx,%edx
     movl    $0,%eax
     call    fpc_write_text_sint
     call    FPC_IOCHECK
     movl    %ebx,%eax
     call    fpc_writeln_end
     call    FPC_IOCHECK
# [23] Writeln(Test(42, GetStr2));
   // here it can not inline GetStr2, because it can not detect whether 
GetStr2 is sideeffect free
     call    fpc_get_output
     movl    %eax,%ebx
     leal    256(%esp),%eax
     call    P$TINLINETEST_$$_GETSTR2$$SHORTSTRING
     leal    256(%esp),%ecx
     movl    %esp,%eax
     movl    $255,%edx
     call    fpc_shortstr_to_shortstr
     movl    $1764,%ecx
     movl    %ebx,%edx
     movl    $0,%eax
     call    fpc_write_text_sint
     call    FPC_IOCHECK
     movl    %ebx,%eax
     call    fpc_writeln_end
     call    FPC_IOCHECK
# [24] end.
     call    FPC_DO_EXIT
     addl    $512,%esp
     popl    %ebx
     ret

=== assembler end ===

So case 2 could be improved a bit.
And for case 3 it might be interesting to have the compiler mark 
functions with additional flags to check whether they are e.g. 
"constant" or access memory (aside from parameters) in a writing way, 
etc. This *might* improve some optimizations...

Regards,
Sven
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freepascal.org/pipermail/fpc-pascal/attachments/20131031/6a73a505/attachment.html>


More information about the fpc-pascal mailing list