I wrote a week ago about some 'Internal compiler error' message. Unfortunately I was using gpc 2.0 and, as Peter Gerwinsky pointed, that was the cause of the error; I downloaded gpc-19981124 from debian.org and now that bug has disappeared.
I am glad to see that the compiler is now much better (although compiling a file with errors often causes strange messages), but I think that I might have found a new bug. The problem arises when calling a destructor inside a dispose statement. I send a program which manifests the problem attached to this message.
Specifically, when the list.done method is called, it should dispose all the items in the list by calling their 'done' destructor. But apparently sometimes this does not happen. When I run the program I get:
descend-init: 1 descend-init: 2 descend-init: 3 descend-init: 4 extracting: descend: 1 descend-done: 1 extracting: descend: 2 extracting: descend: 3 descend-done: 3 extracting: descend: 4
So items 2 and 4 are not freed (or at least their destructors are not called). Changing the line "dispose(extfirst, done);" to "item :=extfirst; dispose(item,done);" solves the problem. I have checked the program in Borland Pascal and it works, so I think is a GPC bug.
BTW, although I plan to join the mailing list in the future I haven't done so yet, so please mail me any answer. Thank you.
type pitem = ^item; item = object prev,next: pitem; constructor init; destructor done; virtual; procedure write; virtual; end;
pdescend = ^descend; descend = object(item) i: integer; constructor init(ii: integer); destructor done; virtual; procedure write; virtual; end;
plist = ^list; list = object first,last: pitem; constructor init; destructor done; function extfirst: pitem; procedure add(l: pitem); procedure adddesc(i: integer); end;
constructor item.init; begin prev :=nil; next :=nil; end;
destructor item.done; begin end;
procedure item.write; begin writeln('item'); end;
constructor descend.init(ii: integer); begin inherited init; i :=ii; writeln('descend-init: ',i); end;
destructor descend.done; begin writeln('descend-done: ',i); inherited done; end;
procedure descend.write; begin writeln('descend: ',i); end;
constructor list.init; begin first :=nil; last :=nil; end;
destructor list.done; begin while (first<>nil) do dispose(extfirst,done); end;
function list.extfirst: pitem; var item: pitem; begin write('extracting: '); first^.write; extfirst :=first; if (first=nil) then exit; item :=first; first :=first^.next; item^.next :=nil; if (first<>nil) then first^.prev :=nil else last :=nil; end;
procedure list.add(l: pitem); begin if (first=nil) then first :=l else last^.next :=l; l^.prev :=last; last :=l; end;
procedure list.adddesc(i: integer); begin add(new(pdescend,init(i))); end;
var alist: plist;
begin new(alist,init); alist^.adddesc(1); alist^.adddesc(2); alist^.adddesc(3); alist^.adddesc(4); dispose(alist,done); end.
Miguel Lobo wrote:
[...] as Peter Gerwinsky pointed [...]
^ Gerwinski. ;-) ^
I am glad to see that the compiler is now much better (although compiling a file with errors often causes strange messages),
If they are "too strange", please post an example here, so we can fix it (even if this job will probably not get highest priority on our list;-).
but I think that I might have found a new bug. The problem arises when calling a destructor inside a dispose statement. I send a program which manifests the problem attached to this message.
Thanks for the report. This is a new instance of a bug we are already working on.
Peter
Hi again!
I just wrote:
Thanks for the report. This is a new instance of a bug we are already working on.
That was wrong, but for the better: It was much easier than I had thought. (Thanks, Frank, for the tip.)
The bug will be fixed in the next GPC beta release coming real soon now. ;-)
Peter