On 07/07/2011 16:54, Alexander Klenin wrote:
On Fri, Jul 8, 2011 at 02:35, Martin<f...@mfriebe.de>  wrote:
On 07/07/2011 16:27, Alexander Klenin wrote:
1) That the code you posted would work quite correctly if "const
string" is fixed,
   including all the optimizations you are suggesting in the rest of
your message.
No.

As I said: IF the result of constant expressions like "s[a] = '<'" are
cached (in future) depending on optimization level, then it breaks.
Well, maybe you should run the code and see for youself --
I do not know how to explain this in even more detail.
It will *only* break due to the current optimization bug.
Remove the bug, and no breakage is possible,
with or without caching you describe.
Even now, if you ensure refcount>1, no breakage is possible.

The 2nd evaluation, of this expression without optimization returns a
different result from the 1st evaluation. (It may be that the example would
need updating, but there is code where this can happen, including if
ref-counting was done)

So depending on the 2nd evaluation being done, or cached (future
optimization) the program flow differs.
It only differs now due to the current optimization bug.
Remove the bug, and the code will stop breaking.

Ok, so here I go, an example without "const" => that means the refcount is increased.

Yet it crashes.
But the crash is NOT the issue. After all this crash is not caused by "const". there is no const.
this crash is simply wrong code....

But it shows something else.
It shows that even with refcount in place, it is possible to modify (via a global var) the content of a local string.

Yes, I use pointers, but it does not matter how I managed to change the content of "s". All that matters is, that I broke the promise (assuming s was declared const")

But as soon as the content of s changes (and if s was declared const), the behaviour is simply unpredictable.

Because the second "s[2] = 'x'" *could* be cached *or* evaluated; leading to a different execution path



-------

program Project1; {$mode objfpc}{$H+}
uses Classes;

var Foo: String;

procedure Ouch(a: pchar);
begin
  a[0] := 'x';
end;

procedure Test1(  (*const*)  s: String);
var x: TStringList;
begin
  if s[2] = 'x' then
    x := TStringList.Create;
  Ouch(@Foo[2]);
  if s[2] = 'x' then
    x.Add('lets hope');
end;

begin
  Foo := 'ab'+'12';
  Test1(Foo);
  readln;
end.

_______________________________________________
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel

Reply via email to