Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-devel / 2005-02

Internal error in Delphi mode

13 messages · 6 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Craig Peterson

Hi All,

I've just recently started using Free Pascal through the Lazarus project, and I've found a bit of my code which is causing problems with the compiler.

I've attached the complete sample program below. In objfpc mode everything works fine; in delphi mode the Length(c.IntArray[0]) line causes it to fail with an internal error 200405023. Also compiles if I first assign c.IntArray[0] to a variable and then ask for it's length.

I'm compiling using fpc 1.9.6, 2005/01/03, for i386, on Windows 2000.

Regards,
Craig Peterson

program project1;
{$mode delphi}
uses
   types;
type
   TTestClass = class
     function GetIntArray(Index: Integer): TIntegerDynArray;
     property IntArray[Index: Integer]: TIntegerDynArray
       read GetIntArray;
   end;
function TTestClass.GetIntArray(Index: Integer): TIntegerDynArray;
begin
   Result := nil;
end;
var
   c: TTestClass;
   x: Integer;
begin
   c := TTestClass.Create;
   x := Length(c.IntArray[0]);
end.

Reply by email

Peter Vreman
to Craig Peterson
Show quoted text 12 lines
Hi All, I've just recently started using Free Pascal through the Lazarus project, and I've found a bit of my code which is causing problems with the compiler. I've attached the complete sample program below. In objfpc mode everything works fine; in delphi mode the Length(c.IntArray[0]) line causes it to fail with an internal error 200405023. Also compiles if I first assign c.IntArray[0] to a variable and then ask for it's length. I'm compiling using fpc 1.9.6, 2005/01/03, for i386, on Windows 2000.

Already fixed in todays compiler.

Reply by email

Peter Vreman
to Craig Peterson: I've just recently started using Free Pascal through the Lazarus project, and I've found…
Show quoted text 12 lines
Hi All, I've just recently started using Free Pascal through the Lazarus project, and I've found a bit of my code which is causing problems with the compiler. I've attached the complete sample program below. In objfpc mode everything works fine; in delphi mode the Length(c.IntArray[0]) line causes it to fail with an internal error 200405023. Also compiles if I first assign c.IntArray[0] to a variable and then ask for it's length. I'm compiling using fpc 1.9.6, 2005/01/03, for i386, on Windows 2000.

Already fixed in todays compiler.

Reply by email

Joost van der Sluis
to Peter Vreman

Hi all,

the bug-report on the website doesn't work, so I write a mail:

If you assign a widechar to a pwidechar, the refcount isn't increased. This construct is often used in the variants-code, which is allowed, according to the comments at the top of wstrings.inc.

An example:

Program test;
var PW    : PWideChar;
    dummy : AnsiString;
procedure Set_PW;
var
  W : WideString;
  s : ansistring;
begin
  s := 'Hello world'; // Can't assign directly to W, because that's
  W := s;             // interpreted as a constant with a refcount of -1
  PW := PWideChar(W); // <- Bug, refcount of W (and PW) isn't increased
end;                  // <- Memory at @W is deallocated, since refcount=0
begin
  Set_PW;
  SetLength(Dummy,3);   // The dummy is allocated at the same address as PW
  writeln(pchar(PW)[0]); // Should write 'H', but it doesn't
end.

JoJo,
Joost.

Reply by email

peter green
to Joost van der Sluis

this is not a bug

if when someone does pcharvar := ansistringvar or pwidecharvar := widestringvar we increased the refcount every program that used that construct would leak memory.

where compiler automated types like ansistring and widestring meet non automated types like pchar and pwidechar some care is required on the part of the developer. If you don't like this move to a nanny state language like java.

Show quoted text 53 lines
-----Original Message----- From: Behalf Of Joost van der Sluis Sent: 13 February 2005 00:32 To: FPC developers' list Subject: [fpc-devel] Bug in PWidechar and refcounting Hi all, the bug-report on the website doesn't work, so I write a mail: If you assign a widechar to a pwidechar, the refcount isn't increased. This construct is often used in the variants-code, which is allowed, according to the comments at the top of wstrings.inc. An example: Program test; var PW : PWideChar; dummy : AnsiString; procedure Set_PW; var W : WideString; s : ansistring; begin s := 'Hello world'; // Can't assign directly to W, because that's W := s; // interpreted as a constant with a refcount of -1 PW := PWideChar(W); // <- Bug, refcount of W (and PW) isn't increased end; // <- Memory at @W is deallocated, since refcount=0 begin Set_PW; SetLength(Dummy,3); // The dummy is allocated at the same address as PW writeln(pchar(PW)[0]); // Should write 'H', but it doesn't end. JoJo, Joost. _______________________________________________ fpc-devel maillist - http://lists.freepascal.org/mailman/listinfo/fpc-devel

Reply by email

Joost van der Sluis
to peter green
if when someone does pcharvar := ansistringvar or pwidecharvar := widestringvar we increased the refcount every program that used that construct would leak memory.

Normally I would aggree with you, but as far as I can see, PWideChar is also an automated type. (If not then large parts of the variant-code in the RTL has to be rewritten, and probably alsoe the wstrings.inc file)

From wstrings.inc:

WideString is defined as a 'silent' pwidechar :
a pwidechar that points to :

  @-8  : SizeInt for reference count;
  @-4  : SizeInt for size;
  @    : String + Terminating #0;
  Pwidechar(Widestring) is a valid typecast.
  So WS[i] is converted to the address @WS+i-1.

So there is a bug somewhere. But if they should not be refcounted, that's ok. But then I have some fixs for the variant-code

Joost

Reply by email

Alexey Barkovoy
to Joost van der Sluis
Show quoted text 17 lines
Normally I would aggree with you, but as far as I can see, PWideChar is also an automated type. (If not then large parts of the variant-code in the RTL has to be rewritten, and probably alsoe the wstrings.inc file) >From wstrings.inc: WideString is defined as a 'silent' pwidechar : a pwidechar that points to : @-8 : SizeInt for reference count; @-4 : SizeInt for size; @ : String + Terminating #0; Pwidechar(Widestring) is a valid typecast. So WS[i] is converted to the address @WS+i-1. So there is a bug somewhere. But if they should not be refcounted, that's ok. But then I have some fixs for the variant-code

Above is just an internal description of WideString layout in memory, so this layout allows easy type conversion of WideString to PWideChar. Note: PWideChar, PAnsiChar, PChar are just pointers and not garbage collected by compiler. But AnsiString and WideString are compiler managed types. So, as Peter mentioned, behaviour you are seeing is by design.

Reply by email

Peter Vreman
Show quoted text 27 lines
Hi all, the bug-report on the website doesn't work, so I write a mail: If you assign a widechar to a pwidechar, the refcount isn't increased. This construct is often used in the variants-code, which is allowed, according to the comments at the top of wstrings.inc. An example: Program test; var PW : PWideChar; dummy : AnsiString; procedure Set_PW; var W : WideString; s : ansistring; begin s := 'Hello world'; // Can't assign directly to W, because that's W := s; // interpreted as a constant with a refcount of -1 PW := PWideChar(W); // <- Bug, refcount of W (and PW) isn't increased end; // <- Memory at @W is deallocated, since refcount=0

Kylix doesn't increase the refcount. Add the following line before and after the assignment to print the refcount:

  writeln(plongint(pchar(w)-8)^);

Reply by email

Peter Vreman
Show quoted text 27 lines
Hi all, the bug-report on the website doesn't work, so I write a mail: If you assign a widechar to a pwidechar, the refcount isn't increased. This construct is often used in the variants-code, which is allowed, according to the comments at the top of wstrings.inc. An example: Program test; var PW : PWideChar; dummy : AnsiString; procedure Set_PW; var W : WideString; s : ansistring; begin s := 'Hello world'; // Can't assign directly to W, because that's W := s; // interpreted as a constant with a refcount of -1 PW := PWideChar(W); // <- Bug, refcount of W (and PW) isn't increased end; // <- Memory at @W is deallocated, since refcount=0

Kylix doesn't increase the refcount. Add the following line before and after the assignment to print the refcount:

  writeln(plongint(pchar(w)-8)^);

Reply by email

Peter Vreman
Show quoted text 27 lines
Hi all, the bug-report on the website doesn't work, so I write a mail: If you assign a widechar to a pwidechar, the refcount isn't increased. This construct is often used in the variants-code, which is allowed, according to the comments at the top of wstrings.inc. An example: Program test; var PW : PWideChar; dummy : AnsiString; procedure Set_PW; var W : WideString; s : ansistring; begin s := 'Hello world'; // Can't assign directly to W, because that's W := s; // interpreted as a constant with a refcount of -1 PW := PWideChar(W); // <- Bug, refcount of W (and PW) isn't increased end; // <- Memory at @W is deallocated, since refcount=0

Kylix doesn't increase the refcount. Add the following line before and after the assignment to print the refcount:

  writeln(plongint(pchar(w)-8)^);

Reply by email

DrDiettrich
to Alexey Barkovoy: Above is just an internal description of WideString layout in memory, so this layout…
Alexey Barkovoy wrote
PAnsiChar, PChar are just pointers and not garbage collected by compiler. But AnsiString and WideString are compiler managed types. So, as Peter mentioned, behaviour you are seeing is by design.

In Delphi WideString is not reference layout of the string prefix is dictated by the Windows API (BSTR type), and AFAIK Windows also doesn't use reference counting with this type, or with OLEVariants containing wide strings.

DoDi

Reply by email

Peter Vreman
to DrDiettrich
Show quoted text 11 lines
Alexey Barkovoy wrote: > PAnsiChar, PChar are just pointers and not garbage collected by > compiler. But > AnsiString and WideString are compiler managed types. So, as Peter > mentioned, > behaviour you are seeing is by design. In Delphi WideString is not reference layout of the string prefix is dictated by the Windows API (BSTR type), and AFAIK Windows also doesn't use reference counting with this type, or with OLEVariants containing wide strings.

That is something Windows specific. For Kylix it is reference counted.

Reply by email

Alexey Barkovoy
to DrDiettrich: In Delphi WideString is not reference layout of the string prefix is dictated by the…

----- Original Message -----

Earlier message 22 lines
From: "DrDiettrich" To: "FPC developers' list" Sent: Tuesday, February 15, 2005 4:11 AM Subject: Re: [fpc-devel] Bug in PWidechar and refcounting > Alexey Barkovoy wrote: >> PAnsiChar, PChar are just pointers and not garbage collected by compiler. But >> AnsiString and WideString are compiler managed types. So, as Peter mentioned, >> behaviour you are seeing is by design. > > In Delphi WideString is not reference layout of the > string prefix is dictated by the Windows API (BSTR type), and AFAIK > Windows also doesn't use reference counting with this type, or with > OLEVariants containing wide strings. In e-mail above I've not said anywhere about reference-counting, I've said WideString are managed by compiler. For example if you declare WideString local variable in procedure it will be automatically freed at the end of procedure in compiler generated "try ... finally" block. And if you declare PWideChar, allocate memory for it, when it's up to you to free this memory after you no longer need it.

Reply by email