[fpc-devel] Const optimization is a serious bug

michael.vancanneyt at wisa.be michael.vancanneyt at wisa.be
Tue Jul 5 12:24:34 CEST 2011



On Tue, 5 Jul 2011, Martin wrote:

> On 05/07/2011 04:02, Chad Berchek wrote:
>> 
>> Martin wrote:
>>> I don't think it is a bug.
>> ...
>>> "(const s: string)" is a declaration by the programmer, that the
>>> variable (the string) will not be modified at all. That is neither by
>>> the procedure called, nor by any code outside the procedure, via any
>>> other  reference to the data. If the programmer sticks to what he
>>> declared, then it works, if not it crashes.
>> 
>> Is that true? I am not necessarily asserting that your statement is false; 
>> it could well be true. However I personally have not seen it documented so 
>> if anyone has a reference I would like to see it. As far as I have been 
>> able to tell from the docs of Delphi and FPC, the const declaration does 
>> NOT mean the programmer promises to not modify the instance; it means he 
>> promises to not modify the variable, which the compiler does indeed 
>> enforce.
>
> Well, I have pointed out myself,in my mail, that it probably needs more 
> documentation. I do not know if it is documented or not.
>
> But it is the answer, I have gotten several times from developers in the FPC 
> team. So for all I know it is the intended behaviour. At least intended in 
> FPC (and apparently either intended or at least implemented in Delphi). So if 
> there is no documentation for it, then it would appear a problem of 
> documentation, rather than a bug in the compiler (Again all based on the 
> statements I was given)

There is no bug.

You can always fool the compiler. The compiler trusts you and assumes that
what you tell her is true, namely, that the called code will not modify the
const parameter (in the case of an ansistring: a pointer). That's it. 
Based on this she may or may not perform some optimizations.

For what it's worth, you can recreate the alleged problem just as easily in
C or with non-reference-counted classes.

For example:

uses sysutils,classes;

Var
   C : TComponent;

Procedure DoSomething(Const AC : TComponent);

begin
   FreeAndNil(C);
   AC.Name:=AC.Name+'_component'; // You can skip this, even.
   Writeln(AC.Name);
end;

begin
   C:=TComponent.Create(nil);
   C.Name:='Something';
   DoSOmething(C);
end.

Will not produce the desired effect. The compiler cannot warn you against
this.

I understand that with Ansistrings it's slightly more convoluted than this,
but it's the same principle.

Michael.



More information about the fpc-devel mailing list