<html>
  <head>
    <meta content="text/html; charset=ISO-8859-1"
      http-equiv="Content-Type">
  </head>
  <body text="#000000" bgcolor="#FFFFFF">
    <div class="moz-cite-prefix">Am 31.10.2013 09:45, schrieb Michael
      Schnell:<br>
    </div>
    <blockquote cite="mid:527218A3.5050708@lumino.de" type="cite">
      <meta content="text/html; charset=ISO-8859-1"
        http-equiv="Content-Type">
      <div class="moz-cite-prefix">On 10/28/2013 02:47 PM, Dmitry
        Pribysh wrote:<br>
      </div>
      <blockquote cite="mid:292231382968049@web3m.yandex.ru" type="cite">
        <div> </div>
        <div>As it is written in Free Pascal <a moz-do-not-send="true"
href="http://wiki.freepascal.org/Code_Conversion_Guide#Order_of_parameter_evaluation">wiki</a>,
          order of parameter evaluation is not defined in FPC, but it is
          defined in Delphi (Delphi guarantees left-to-right evaluation
          order).</div>
        <br>
      </blockquote>
      IMHO =in fact evaluation of a parameter should not be guaranteed
      at all. <br>
      <br>
      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).<br>
    </blockquote>
    1. FPC does not guarantee evaluation order exactly for this reason<br>
    2. The compiler already does this inlining already in that way (at
    least partially). <br>
    Take this code:<br>
    <br>
    === code begin ===<br>
    <br>
    program tinlinetest;<br>
    <br>
    {$mode objfpc}<br>
    <br>
    function GetStr1: String; inline;<br>
    begin<br>
      Result := 'Hello World';<br>
    end;<br>
    <br>
    function GetStr2: String;<br>
    begin<br>
      Result := 'Hello World';<br>
    end;<br>
    <br>
    function Test(aArg1: Integer; aArg2: String): Integer; inline;<br>
    begin<br>
      Result := aArg1 * 42;<br>
    end;<br>
    <br>
    begin<br>
      Writeln(Test(42, 'Hello World'));<br>
      Writeln(Test(42, GetStr1));<br>
      Writeln(Test(42, GetStr2));<br>
    end.<br>
    <br>
    === code end ===<br>
    <br>
    this will produce this output in the main function (2.7.1 and
    compiled with -O2):<br>
    <br>
    === assembler begin ===<br>
    <br>
    PASCALMAIN:<br>
    .globl    _main<br>
    _main:<br>
    # Temps allocated between esp+0 and esp+512<br>
    # [20] begin<br>
        pushl    %ebx<br>
        addl    $-512,%esp<br>
        call    FPC_INITIALIZEUNITS<br>
    # [21] Writeln(Test(42, 'Hello World'));<br>
      // No usage of 'Hello World' constant here<br>
        call    fpc_get_output<br>
        movl    %eax,%ebx<br>
        movl    %ebx,%edx<br>
        movl    $1764,%ecx<br>
        movl    $0,%eax<br>
        call    fpc_write_text_sint<br>
        call    FPC_IOCHECK<br>
        movl    %ebx,%eax<br>
        call    fpc_writeln_end<br>
        call    FPC_IOCHECK<br>
    # [22] Writeln(Test(42, GetStr1));<br>
      // here this might be a bug... the compiler inlines GetStr1, but
    does not detect that its result is constant and not used...<br>
        call    fpc_get_output<br>
        movl    %eax,%ebx<br>
        movl    $_$TINLINETEST$_Ld1,%ecx<br>
        leal    256(%esp),%eax<br>
        movl    $255,%edx<br>
        call    fpc_shortstr_to_shortstr<br>
        leal    256(%esp),%ecx<br>
        movl    %esp,%eax<br>
        movl    $255,%edx<br>
        call    fpc_shortstr_to_shortstr<br>
        movl    $1764,%ecx<br>
        movl    %ebx,%edx<br>
        movl    $0,%eax<br>
        call    fpc_write_text_sint<br>
        call    FPC_IOCHECK<br>
        movl    %ebx,%eax<br>
        call    fpc_writeln_end<br>
        call    FPC_IOCHECK<br>
    # [23] Writeln(Test(42, GetStr2));<br>
      // here it can not inline GetStr2, because it can not detect
    whether GetStr2 is sideeffect free<br>
        call    fpc_get_output<br>
        movl    %eax,%ebx<br>
        leal    256(%esp),%eax<br>
        call    P$TINLINETEST_$$_GETSTR2$$SHORTSTRING<br>
        leal    256(%esp),%ecx<br>
        movl    %esp,%eax<br>
        movl    $255,%edx<br>
        call    fpc_shortstr_to_shortstr<br>
        movl    $1764,%ecx<br>
        movl    %ebx,%edx<br>
        movl    $0,%eax<br>
        call    fpc_write_text_sint<br>
        call    FPC_IOCHECK<br>
        movl    %ebx,%eax<br>
        call    fpc_writeln_end<br>
        call    FPC_IOCHECK<br>
    # [24] end.<br>
        call    FPC_DO_EXIT<br>
        addl    $512,%esp<br>
        popl    %ebx<br>
        ret<br>
    <br>
    === assembler end ===<br>
    <br>
    So case 2 could be improved a bit.<br>
    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...<br>
    <br>
    Regards,<br>
    Sven<br>
  </body>
</html>