Recent

Author Topic: Best way to initialize a typed const static array?  (Read 1263 times)

dculp

  • Full Member
  • ***
  • Posts: 115
Best way to initialize a typed const static array?
« on: September 16, 2020, 07:09:39 pm »
The following works OK for typed const Array1 but seems awkward (also, not good for very large arrays).

Code: Pascal  [Select][+][-]
  1. program Test;
  2.  
  3. type
  4.         Test_array: array[0..255] of byte;
  5.             {Also used by other procedures (not shown) in addition to Test1}
  6.  
  7.         procedure Test1;
  8.        
  9.         const
  10.                 Array1: Test_array=
  11.                         (0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  12.                          0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  13.                          0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  14.                          0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  15.                          0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  16.                          0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  17.                          0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
  18.                
  19.         begin
  20.         Do something to change a value in Array1;
  21.                 { ***** resulting change must be preserved between calls to Test1 ***** }
  22.         end;
  23.        
  24. begin
  25. Test1;
  26. end.
  27.  

Note that any changes to Array1 must be preserved between calls to Test1 which is why it is declared as a typed const.

Is there a better way to initialize Array1 other than declaring every member? (I realize that Array1 could be declared as a global var to preserve between calls to Test1 but this doesn't seem appropriate since Array1 is only used in Test1.)

(Sorry about the large code indentations due to my editor.)

Thanks,
Don C.

lucamar

  • Hero Member
  • *****
  • Posts: 3204
Re: Best way to initialize a typed const static array?
« Reply #1 on: September 16, 2020, 07:43:26 pm »
There's no better way if you want to do it like that, with an initialized constant.

Note, though, that typed constants are, very basically, "static" vars so if all the members have the same value a better way to initialize it might be with a simple loop at the entry of the routine (perhaps in an inner function?), checking first whether it's already initialized by e.g. looking to the arrays length.

An alternative for really large arrays with different values for each member might be to load them from a file but it doesn't seem to be needed for what you seem to want.


ETA: Never mind, it can't be done with a local constant; it must be a global var to do it that way. I thought it could be declared as:
Code: Pascal  [Select][+][-]
  1. const Array1: Test_array = Nil;
but the compiler doesn't agree with me ... :-[
« Last Edit: September 16, 2020, 08:01:25 pm by lucamar »
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus/FPC 2.0.8/3.0.4 & 2.0.10/3.2.0 - 32/64 bits on:
(K|L|X)Ubuntu 12..18, Windows XP, 7, 10 and various DOSes.

Blaazen

  • Hero Member
  • *****
  • Posts: 2994
  • POKE 54296,15
    • Eye-Candy Controls
Re: Best way to initialize a typed const static array?
« Reply #2 on: September 16, 2020, 07:59:48 pm »
If you need just zeros:  :)
Code: Pascal  [Select][+][-]
  1. {$MACRO ON}
  2. {$define zeros:=0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}
  3. type
  4.   Test_array = array[0..255] of byte;  
  5. ...
  6. const Array1: Test_array = (zeros,zeros,zeros,zeros,zeros,zeros,zeros,zeros,
  7.                             zeros,zeros,zeros,zeros,zeros,zeros,zeros,zeros);
Lazarus 2.1.0 r64115 FPC 3.3.1 r40507 x86_64-linux-qt Chakra, Qt 4.8.7/5.13.2, Plasma 5.17.3
Lazarus 1.8.2 r57369 FPC 3.0.4 i386-win32-win32/win64 Wine 3.21

Try Eye-Candy Controls: https://sourceforge.net/projects/eccontrols/files/

Thaddy

  • Hero Member
  • *****
  • Posts: 10573
Re: Best way to initialize a typed const static array?
« Reply #3 on: September 16, 2020, 09:15:06 pm »
Default()
 >:D

dculp

  • Full Member
  • ***
  • Posts: 115
Re: Best way to initialize a typed const static array?
« Reply #4 on: September 16, 2020, 09:47:41 pm »
Default()
 >:D

I can't find anything about "Default()". Can you provide a little more info and/or code snippet?

Lazarus 2.0.2
FPC 3.0.4
Windows 7, 10

bytebites

  • Sr. Member
  • ****
  • Posts: 345
Re: Best way to initialize a typed const static array?
« Reply #5 on: September 16, 2020, 10:05:17 pm »
Code: Pascal  [Select][+][-]
  1. Array1:= Default(Test_array)
but then Array1 can't be const.

ASerge

  • Hero Member
  • *****
  • Posts: 1693
Re: Best way to initialize a typed const static array?
« Reply #6 on: September 16, 2020, 10:35:09 pm »
Is there a better way to initialize Array1 other than declaring every member?
If you need to initialize only with zeros, you can do this:
Code: Pascal  [Select][+][-]
  1. {$APPTYPE CONSOLE}
  2. {$MODE OBJFPC}
  3.  
  4. type
  5.   TArray = array[0..255] of Byte;
  6.  
  7.   procedure Test1;
  8.   type
  9.     TWrapper = record
  10.       A: TArray;
  11.     end;
  12.   {$PUSH}
  13.   {$WARN 3177 off : Some fields coming after "$1" were not initialized}
  14.   const
  15.     W: TWrapper = ();
  16.   {$POP}
  17.   begin
  18.     Inc(W.A[0]);
  19.     Writeln(W.A[0]);
  20.     //Do something to change a value in W.A;
  21.           { ***** resulting change must be preserved between calls to Test1 ***** }
  22.   end;
  23.  
  24. begin
  25.   Test1;
  26.   Test1;
  27.   Readln;
  28. end.

440bx

  • Hero Member
  • *****
  • Posts: 2048
Re: Best way to initialize a typed const static array?
« Reply #7 on: September 17, 2020, 04:04:57 am »
@Serge

Code: Pascal  [Select][+][-]
  1.   const
  2.     W: TWrapper = ();
  3.  

I can't find where the "= ()" is in the documentation.  Would you happen to have a link where that construction is documented ?

Thank you.
FPC v3.0.4 and Lazarus 1.8.2 on Windows 7 64bit.

PascalDragon

  • Hero Member
  • *****
  • Posts: 2418
  • Compiler Developer
Re: Best way to initialize a typed const static array?
« Reply #8 on: September 17, 2020, 09:24:48 am »
Default()
 >:D

That won't help here, because Default can't be used in a constant (yet) and using it in code would defeat dculp's purpose of using a typed, writeable constant.

Code: Pascal  [Select][+][-]
  1.   const
  2.     W: TWrapper = ();
  3.  

I can't find where the "= ()" is in the documentation.  Would you happen to have a link where that construction is documented ?

Seems like the documentation is missing the part about how the values for a constant look like... Anyway, that's just a record constant that usually looks like this:

Code: Pascal  [Select][+][-]
  1. type
  2.   TPoint = record
  3.     x, y: LongInt;
  4.   end;
  5.  
  6. const
  7.   Zero: TPoint = (x: 0; y: 0);

If you skip fields the compiler will warn that fields are missing which is why ASerge disabled warning 3177. Though I have to admit that I hadn't expected that to work without any fields... :-[

Edit: Correction, the entry about Typed constants contains a link to 4.4 Initialized Variables which explains the syntax.
« Last Edit: September 17, 2020, 09:37:17 am by PascalDragon »

440bx

  • Hero Member
  • *****
  • Posts: 2048
Re: Best way to initialize a typed const static array?
« Reply #9 on: September 17, 2020, 02:37:04 pm »
If you skip fields the compiler will warn that fields are missing which is why ASerge disabled warning 3177. Though I have to admit that I hadn't expected that to work without any fields... :-[
That's what I expected as well.  "Normally" when initializing a static (in the C sense) array and elements are missing, the compiler usually emits an error stating that it expected "x" additional elements.

Thank you for the link but, unless I missed it, I don't see anywhere in there that the list can be left empty (and apparently this is only possible when the array is in a record.)  Should this be reported as a documentation bug ?

FPC v3.0.4 and Lazarus 1.8.2 on Windows 7 64bit.

PascalDragon

  • Hero Member
  • *****
  • Posts: 2418
  • Compiler Developer
Re: Best way to initialize a typed const static array?
« Reply #10 on: September 18, 2020, 09:28:05 am »
If you skip fields the compiler will warn that fields are missing which is why ASerge disabled warning 3177. Though I have to admit that I hadn't expected that to work without any fields... :-[
That's what I expected as well.  "Normally" when initializing a static (in the C sense) array and elements are missing, the compiler usually emits an error stating that it expected "x" additional elements.

For arrays the compiler will generate an error. For records however it will assume the fields as 0 (this is Delphi compatible). You are of course always free to set warning 3177 to error. ;)

Thank you for the link but, unless I missed it, I don't see anywhere in there that the list can be left empty (and apparently this is only possible when the array is in a record.)  Should this be reported as a documentation bug ?

Well, the documentation does say this (emphasis mine):

Quote
For constant records, each element of the record should be specified,

Of course that can be made clearer... so feel free to file a documentation bug if you want.

440bx

  • Hero Member
  • *****
  • Posts: 2048
Re: Best way to initialize a typed const static array?
« Reply #11 on: September 18, 2020, 02:38:49 pm »
Of course that can be made clearer... so feel free to file a documentation bug if you want.
Clearer is always desirable.  Reported it as a documentation bug.

Tracker id : 37771
FPC v3.0.4 and Lazarus 1.8.2 on Windows 7 64bit.

Paolo

  • Jr. Member
  • **
  • Posts: 68
Re: Best way to initialize a typed const static array?
« Reply #12 on: September 19, 2020, 01:11:35 pm »
I don't know if this fits the needs but there is the Fillchar procedure that can be used to fill a memory block with the same char.

procedure FillChar( var x;  count: SizeInt;  Value: Char);

ASerge

  • Hero Member
  • *****
  • Posts: 1693
Re: Best way to initialize a typed const static array?
« Reply #13 on: September 20, 2020, 04:47:39 pm »
I don't know if this fits the needs but there is the Fillchar procedure that can be used to fill a memory block with the same char.
Only need to do this once at the start of the program and only inside the function. We will have to put the variable outside the scope of the function (globally), which the author wanted to avoid. If we use the heap, when will we release it?

 

TinyPortal © 2005-2018