Lazarus

Free Pascal => General => Topic started by: mw108 on July 12, 2018, 07:59:35 pm

Title: Data element too large
Post by: mw108 on July 12, 2018, 07:59:35 pm
Why is this causing a "Data element too large" error?

Code: Pascal  [Select][+][-]
  1. program Test;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. uses
  6.         FGL;
  7.  
  8. type
  9.         TTinyImagechannel = packed array[0..31, 0..31] of Byte;
  10.         TTinyImage = packed record
  11.                 bLabel: Byte;
  12.                 R, G, B: TTinyImageChannel;
  13.         end;
  14.  
  15.         TTinyImageList = specialize TFPGList<TTinyImage>;
  16.  
  17. begin
  18. end.
  19.  

The size of the TTinyImage record is 3073 bytes.
Title: Re: Data element too large
Post by: marcov on July 12, 2018, 08:04:12 pm
Most fgl container types are for pointers.

So probably internally it defines a rather large type (pointer to array of T) .

Title: Re: Data element too large
Post by: mw108 on July 12, 2018, 09:23:56 pm
So can this be considered a bug? Or what could be a solution here, other than using an Array of TTinyImage instead of a list?

I know FPC isn't Delphi and that Generics generation works different in both. But same idea compiles without problems in Delphi.

Code: Pascal  [Select][+][-]
  1. program Project1;
  2.  
  3. {$APPTYPE CONSOLE}
  4.  
  5. {$R *.res}
  6.  
  7. uses
  8.   System.SysUtils,
  9.   Generics.Collections;
  10.  
  11. type
  12.   TTinyImagechannel = packed array[0..31, 0..31] of Byte;
  13.   TTinyImage = packed record
  14.     bLabel: Byte;
  15.     R, G, B: TTinyImageChannel;
  16.   end;
  17.  
  18.   TTinyImageList = TList<TTinyImage>;
  19.  
  20. begin
  21.   try
  22.  
  23.   except
  24.     on E: Exception do
  25.       Writeln(E.ClassName, ': ', E.Message);
  26.   end;
  27. end.
  28.  
Title: Re: Data element too large
Post by: ASerge on July 12, 2018, 10:14:34 pm
Why is this causing a "Data element too large" error?
Which version FPC?
This work in 3.0.4:
Code: Pascal  [Select][+][-]
  1. program Project1;
  2. {$MODE OBJFPC}
  3. {$APPTYPE CONSOLE}
  4. {$MODESWITCH ADVANCEDRECORDS}
  5.  
  6. uses fgl;
  7.  
  8. type
  9.   TTinyImageChannel = packed array[0..31, 0..31] of Byte;
  10.  
  11.   TTinyImage = packed record
  12.     bLabel: Byte;
  13.     R, G, B: TTinyImageChannel;
  14.     class operator = (const Left, Right: TTinyImage): Boolean;
  15.   end;
  16.  
  17.   TTinyImageList = specialize TFPGList<TTinyImage>;
  18.  
  19. class operator TTinyImage.=(const Left, Right: TTinyImage): Boolean;
  20. begin
  21.   Result := False;
  22. end;
  23.  
  24. var
  25.   X: TTinyImageList;
  26. begin
  27.   X := TTinyImageList.Create;
  28.   Writeln(X.ItemSize); // 3073
  29.   X.Free;
  30.   Readln;
  31. end.
Title: Re: Data element too large
Post by: Leledumbo on July 13, 2018, 07:12:52 am
But same idea compiles without problems in Delphi.
This code is FPC compatible, just a little {$mode delphi} and System.SysUtils -> SysUtils renaming and you're done.
Title: Re: Data element too large
Post by: Thaddy on July 13, 2018, 08:05:06 am
But same idea compiles without problems in Delphi.
This code is FPC compatible, just a little {$mode delphi} and System.SysUtils -> SysUtils renaming and you're done.
The delphi code? yes! Just what you wrote.
Indeed. Note that rtl-generics is trunk. There is a 3.0.4. version available as separate download from the author.
In general I strongly advice to use mode delphi if you are coming from delphi and NOT mode objfpc. It has no real advantages and makes porting unnecessary difficult.
The limit is here in FGL. Not a bug but a declared limitation. FGL is not delphi compatible. rtl-generics is largely delphi compatible and even includes extra's.
So: use mode delphi and use rtl-generics. Not mode objfpc and fgl.
Title: Re: Data element too large
Post by: mw108 on July 13, 2018, 01:59:19 pm
Which version FPC?
This work in 3.0.4:
[...]
Unfortunately, not here. See attachment. What are you using? Windows or Linux? I'm using Windows 10 here.

This code is FPC compatible, just a little {$mode delphi} and System.SysUtils -> SysUtils renaming and you're done.
What about the Generics?

FPC doesn't like this either:

Code: Pascal  [Select][+][-]
  1. program Test2;
  2. {$MODE DELPHI}
  3. {$APPTYPE CONSOLE}
  4. {$MODESWITCH ADVANCEDRECORDS}
  5.  
  6. uses SysUtils, Classes;
  7.  
  8. type    
  9.         TTinyImageChannel = packed array[0..31, 0..31] of Byte;
  10.         TTinyImage = packed record
  11.                         bLabel: Byte;
  12.                         R, G, B: TTinyImageChannel;
  13.         end;
  14.         TTinyImageList = TList<TTinyImage>; // <-- Error: Identifier not found "TList$1"
  15.  
Title: Re: Data element too large
Post by: marcov on July 13, 2018, 02:50:14 pm
What about the Generics?

FPC doesn't like this either:

If I add "generics.collections"  to the uses clause as mandated by delphi it works fine for me with 3.1.1
Title: Re: Data element too large
Post by: Thaddy on July 13, 2018, 03:32:41 pm
Which is exactly what Leledumbo explained:
Code: Pascal  [Select][+][-]
  1. program Project1;
  2. {$IFDEF FPC}{$MODE DELPHI}{$ENDIF}
  3. {$IFDEF WINDOWS}{$APPTYPE CONSOLE}{$ENDIF}
  4.  
  5. //{$R *.res} // silly delphi
  6.  
  7. uses
  8.   {$ifndef fpc}System.{$endif}SysUtils,
  9.   Generics.Collections;
  10.  
  11. type
  12.   TTinyImagechannel = packed array[0..31, 0..31] of Byte;
  13.   TTinyImage = packed record
  14.     bLabel: Byte;
  15.     R, G, B: TTinyImageChannel;
  16.   end;
  17.  
  18.   TTinyImageList = TList<TTinyImage>;
  19.  
  20. begin
  21.   try
  22.  
  23.   except
  24.     on E: Exception do
  25.       Writeln(E.ClassName, ': ', E.Message);
  26.   end;
  27. end.
Title: Re: Data element too large
Post by: mw108 on July 13, 2018, 03:56:44 pm
If I add "generics.collections"  to the uses clause as mandated by delphi it works fine for me with 3.1.1
I tried adding Generics.Collections, but FPC says it is unknown.

https://i.imgur.com/nNxZAIT.png

Which is exactly what Leledumbo explained:
Yes, thats what I tried. But see above. FPC says it can't find that unit.
Title: Re: Data element too large
Post by: Thaddy on July 13, 2018, 04:09:33 pm
You have to install rtl-generics for fpc 3.0.4. from here : https://github.com/maciej-izak/generics.collections
Because atm it is still just in trunk.

Don't worry. Code is almost the same and stable.

BTW: I already wrote that!
Title: Re: Data element too large
Post by: mw108 on July 13, 2018, 04:25:57 pm
Ah, thats what you meant with ...

Quote
Note that rtl-generics is trunk. There is a 3.0.4. version available as separate download from the author.

... Sorry, I didn't register that. :)

Thanks for the help.
Title: Re: Data element too large
Post by: PascalDragon on July 17, 2018, 09:29:55 pm
Most fgl container types are for pointers.

So probably internally it defines a rather large type (pointer to array of T) .

It was indeed a large type due to some miscalculations, though this only really manifested itself on 32-bit systems. I've fixed the declaration used there in revision 39464 (and it should be mostly backwards compatible)
TinyPortal © 2005-2018