[fpc-devel] Const optimization is a serious bug

Max Vlasov max.vlasov at gmail.com
Sat Jul 9 11:18:47 CEST 2011


On Sat, Jul 9, 2011 at 4:13 AM, Martin <fpc at mfriebe.de> wrote:
> On 09/07/2011 00:59, Max Vlasov wrote:
>>
>> On Sat, Jul 9, 2011 at 3:14 AM, Martin<fpc at mfriebe.de>  wrote:
>>>
>>> function CRCConstString(constref Str: string): integer;
>>> does what you describ
>>
>> Hmm, it's interesting.. Some observations:
>> - constref is implemented in 2.5.1, right? Unfortunately I can not
>> test it right now in 2.4.2, it refuses to recognize it, but I I want
>> to test it.
>> - In LCL it used only with interfaces and TGuid's, no strings or other
>> structures
>> - there are not much information about constrefs in Lazarus, several
>> posts, the largest part of them is yours, Martin :) so you're probably
>> one of the few who really understand it  :)
>
> Well the LCL can't use it, if it's trunk only (except if IFDEFed). The LCL
> should compile with release fpc...
>
> See:
> http://wiki.lazarus.freepascal.org/FPC_New_Features_Trunk#Constref_parameter_modifier
>
> - See difference to normal "const" is " that it must be passed by
> reference."
>
> - Note (same as const) it is described as: "This modifier means that the
> compiler can assume that the parameter is constant"
> The "assume" means that the requirement for constant-ness goes above that
> what the compiler can enforce (that is: the compiler can enforce only the
> local var; but constant implies the value by any means of access)
>
> With what the compiler does today (afaik) none-constantness would not cause
> any harm (yet). Unless you count it as harm (and you should) that future FPC
> may (= "is allowed to") compile your code (without any warning or hint) into
> an exe that behaves different.
>

Thanks for your notes, Martin. I compiled the trunk fpc (2.5.1) and
compile the example with constref

function TForm33.CRCConstRef(constref Str: string): integer;
var
  i: integer;
begin
  Result:=0;
  for i:=1 to Length(Str) do
    Result:=Result + Ord(Str[i]);
end;

it worked, also the timing is exactly the same as for PString, so your
information (PString = constref Str) is indirectly confirmed. Btw,
Chad's example also worked

I understand that currently it works also because as you mentioned the
compiler doesn't apply special optimization, sure it could. But also
it's possible to forbid it for this special case. Since ansistring is
a special entity, not present in COM at all, so with regard to
"standards" it can be fully internal decision. Also since there are no
consref in Delphi as I suppose, they can't be the authority in this
regard :)

If everything it taken care of, apart from possibly global switch to
do const = constref aliasing, lcl also can gradually (when fpc 2.5.1
becomes requirement) replace const with constref in critical places
(for example when probable events can be fired). Sure this can break
inheritance, so just a thought to think about.

Max



More information about the fpc-devel mailing list