<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta content="text/html; charset=UTF-8" http-equiv="Content-Type">
</head>
<body text="#000000" bgcolor="#ffffff">
Here is what happens<br>
<br>
<br>
procedure TfrmFileAssoc.btnAddNewTypeClick(Sender: TObject);<br>
begin<br>
edtIconFileName.Text:= TExtAction(Exts.Items[0]).Icon;<br>
end;<br>
procedure TfrmFileAssoc.edtIconFileNameChange(Sender: TObject);<br>
begin<br>
TExtAction(Exts.Items[0]).Icon := GenName; //DateTimeToStr(Now);<br>
end;<br>
<br>
<br>
1) btnAddNewTypeClick.<br>
Takes the string from ExtAction(Exts.Items[0]).Icon;<br>
This string has a ref-count of 1 (not sure why it shows 2 in your
debug)<br>
<br>
2) SetText(const AValue: String)<br>
because AValue is constant, it is not expected to change. The
compiler optimizes the code, the ref-count is not increased. This
does save the need to insert a hidden try-finally block, which
otherwhis would be requiredm, to ensure that the refcout was
decreased at the end of SetText (even if an exception occurred).
Those implicit tr-finally blocks have a noticeable effect on speed.<br>
<br>
3) Going through RealSetText, but then calling you event handler:
edtIconFileNameChange <br>
<br>
4) edtIconFileNameChange <br>
Releases the string referred to by ExtAction(Exts.Items[0]).Icon;<br>
=> memory is freed<br>
AValue now points to freed memory => it didn't expect that the
value was changed.<br>
<br>
Since AValue points to freed memory, it will crash on the next
attempt to use it.<br>
<br>
<br>
----<br>
This is actually part of the definition of "const" for parameters.<br>
<br>
const does mean that you as programmer (or in this case the person
who wrote it) declares that no code anywhere will change the value
of this variable (which includes calling code)<br>
<br>
As a side effect, if using code, the compiler will give you an
error, if you try to modify it inside that procedure. Because the
compiler can detect that, and because you promised the compiler not
to do it.<br>
But the compiler expects that promise to be kept outside the given
procedure too.<br>
<br>
<br>
You code does not keep the promise, which some one else made....
Ouch.<br>
<br>
Obviously it could be argued, the LCL should not make such promises.
It's a decision to be made (and probably to be reviewed now)<br>
<br>
<br>
<br>
<br>
<br>
<br>
On 26/05/2011 22:21, cobines wrote:
<blockquote
cite="mid:BANLkTin50TeCCNom+s=X2RZoeW06__ZSzg@mail.gmail.com"
type="cite">
<pre wrap="">I have added some debugging text in two functions that set text to a
control: TWinControl.RealSetText and widgetset specific
TWin32WSWinControl.SetText (like in attached diff).
This is a log from execution of a program when it crashes:
TWin32WSWinControl.SetText before 0005FBD8 refcount=2 size=17
TWin32WSWinControl.SetText after 0005FBD8 refcount=2 size=17
TWin32WSWinControl.SetText before 00066D10 refcount=3 size=3
TWin32WSWinControl.SetText after 00066D10 refcount=3 size=3
TWinControl.RealSetText before 00526F18 refcount=-1 size=15
TWin32WSWinControl.SetText before 00526F18 refcount=-1 size=15
TWin32WSWinControl.SetText after 00526F18 refcount=-1 size=15
TWinControl.RealSetText after 00526F18 refcount=-1 size=15
TWinControl.RealSetText before 0007F8A0 refcount=1 size=55
TWin32WSWinControl.SetText before 0007F8A0 refcount=1 size=55
TWin32WSWinControl.SetText after 0007F8A0 refcount=522612 size=0
TWinControl.RealSetText after 0007F8A0 refcount=522612 size=0
TWinControl.RealSetText before 00056A80 refcount=1 size=17
TWin32WSWinControl.SetText before 00056A80 refcount=1 size=17
TWin32WSWinControl.SetText after 00056A80 refcount=355076 size=0
TWinControl.RealSetText after 00056A80 refcount=355076 size=354980
In TWin32WSWinControl.SetText there is corruption of the string record
(but the contents are fine).
Now, if I change
procedure TControl.SetText(const Value: TCaption);
to
procedure TControl.SetText(Value: TCaption);
everything is fine:
TWin32WSWinControl.SetText before 0005FBD8 refcount=2 size=17
TWin32WSWinControl.SetText after 0005FBD8 refcount=2 size=17
TWin32WSWinControl.SetText before 00066D10 refcount=3 size=3
TWin32WSWinControl.SetText after 00066D10 refcount=3 size=3
TWinControl.RealSetText before 00526F18 refcount=-1 size=15
TWin32WSWinControl.SetText before 00526F18 refcount=-1 size=15
TWin32WSWinControl.SetText after 00526F18 refcount=-1 size=15
TWinControl.RealSetText after 00526F18 refcount=-1 size=15
TWinControl.RealSetText before 0007F8A0 refcount=2 size=55
TWin32WSWinControl.SetText before 0007F8A0 refcount=2 size=55
TWin32WSWinControl.SetText after 0007F8A0 refcount=1 size=55
TWinControl.RealSetText after 0007F8A0 refcount=1 size=55
TWinControl.RealSetText before 0007F910 refcount=2 size=53
TWin32WSWinControl.SetText before 0007F910 refcount=2 size=53
TWin32WSWinControl.SetText after 0007F910 refcount=1 size=53
TWinControl.RealSetText after 0007F910 refcount=1 size=53
--
cobines
</pre>
<pre wrap="">
<fieldset class="mimeAttachmentHeader"></fieldset>
--
_______________________________________________
Lazarus mailing list
<a class="moz-txt-link-abbreviated" href="mailto:Lazarus@lists.lazarus.freepascal.org">Lazarus@lists.lazarus.freepascal.org</a>
<a class="moz-txt-link-freetext" href="http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus">http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus</a>
</pre>
</blockquote>
<br>
</body>
</html>