Recent

Author Topic: Pointer math and (un)packed arrays  (Read 1259 times)

440bx

  • Hero Member
  • *****
  • Posts: 1086
Re: Pointer math and (un)packed arrays
« Reply #15 on: July 08, 2019, 04:49:52 pm »
I don't even know where you got that from. There is no such.
Serge, what you are referring to is record packing not array packing.

ETA: accurately stated the above should not be just "record packing" but element data type packing.

The modifier "packed" does not change in any way  the way an array is going to arrange its elements, it only acts on the element's data type (if and when applicable.)

There will never be gaps between array elements no matter how the array is declared, packed or unpacked.  An array will always take a series of records/elements (records or otherwise) and arrange them sequentially in memory.  The modifier "packed" _may_ affect the size of the records/elements but, it will never affect the sequential arrangement (one element after the other without gaps between them.)


« Last Edit: July 08, 2019, 05:13:08 pm by 440bx »
using FPC v3.0.4 and Lazarus 1.8.2 on Windows 7 64bit.

Thaddy

  • Hero Member
  • *****
  • Posts: 8679
Re: Pointer math and (un)packed arrays
« Reply #16 on: July 08, 2019, 06:10:57 pm »
There will never be gaps between array elements no matter how the array is declared, packed or unpacked.  An array will always take a series of records/elements (records or otherwise) and arrange them sequentially in memory.  The modifier "packed" _may_ affect the size of the records/elements but, it will never affect the sequential arrangement (one element after the other without gaps between them.)
This is not true for all platforms. E.g. on 16 bit Windows there can be gaps if the sequential range is not exactly aligned to page boundaries. They may still be sequential, but there will be gaps. Even on Win32/64.
Sequential just means "in-order". You can not assume there are no gaps. So: "one element after the other without gaps between them."

Actually, it is not true at all. The memory manager can also play its part....That can be as simple as a linked list, which also defeats your assumptions.
You mean contiguous memory, and that is not the case.
It is also not FreePascal specific. The same happens in C and the likes.
« Last Edit: July 08, 2019, 06:17:32 pm by Thaddy »
Most people that want to use threading should learn to patch their jeans first: use a needle.

440bx

  • Hero Member
  • *****
  • Posts: 1086
Re: Pointer math and (un)packed arrays
« Reply #17 on: July 08, 2019, 06:37:01 pm »
Thaddy,

After reading your post, I have a recommendation for you, it is: stop smoking red paint for breakfast.

It's not good for you.
using FPC v3.0.4 and Lazarus 1.8.2 on Windows 7 64bit.

ASerge

  • Hero Member
  • *****
  • Posts: 1392
Re: Pointer math and (un)packed arrays
« Reply #18 on: July 08, 2019, 08:10:11 pm »
Serge, what you are referring to is record packing not array packing.
On the contrary, it is you think only about "record packed". The documentation explicitly says that packed applies to any structured type, which is either an array or a record.
Very simple proof:
Code: Pascal  [Select]
  1. {$APPTYPE CONSOLE}
  2. {$ALIGN ON}
  3. var
  4.   A: packed array[0..1] of record
  5.       W: Word;
  6.       X: Byte;
  7.     end;
  8. begin
  9.   Writeln(SizeOf(A));
  10.   Readln;
  11. end.
If your statements were true, the array elements would be packed and array size would be 6. But it's not. It is equal to 8, because packed refers only to the array. But if add "packed" before "record" in the definition, only then array size turn to 6.

440bx

  • Hero Member
  • *****
  • Posts: 1086
Re: Pointer math and (un)packed arrays
« Reply #19 on: July 08, 2019, 09:17:08 pm »
If your statements were true, the array elements would be packed and array size would be 6. But it's not. It is equal to 8, because packed refers only to the array. But if add "packed" before "record" in the definition, only then array size turn to 6.
The statement is true, the problem is that prefixing an array with "packed" has an effect only on some, not all, types.  In the case of FPC specifically, if {$bitpacking ON} is in effect _and_ the type is Boolean, then the modifier "packed" will do something, otherwise it won't.

As the first example I posted showed, "packed" is, in most cases, completely ignored.  with the exception of Boolean (in the case of FPC), if the programmer wants the type to be packed, then the programmer has to include "packed" in the type definition, specifying it in front of "array" won't do anything (again, except in the case of Boolean, which seems to be the only exception.)

This can be shown with a small addition to the example you posted
Code: Pascal  [Select]
  1. {$APPTYPE CONSOLE}
  2. {$ALIGN ON}
  3.  
  4. var
  5.   A: packed array[0..1] of record
  6.       W: Word;
  7.       X: Byte;
  8.     end;
  9.  
  10.   B : array[0..1] of packed record
  11.       W : word;
  12.       X : byte;
  13.   end;
  14.  
  15. begin
  16.   Writeln('A: ', SizeOf(A));
  17.   writeln('B: ', sizeof(B));
  18.  
  19.   Readln;
  20. end.        
You can comment/uncomment the ALIGN directive, the result will be the same.  "packed" in front of "array" has no effect whatsoever on, neither, the array or the elements of the array (but, it would affect the type if the type was Boolean, which seems to be the only exception and only when bitpacking is on.)

The important thing is, even when "packed" does something, it does not alter the way elements are arranged in the array, it only alters the representation of the stored type (yet again, in the case of FPC, only if the array's target type is Boolean, otherwise it does nothing.)

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

SymbolicFrank

  • Hero Member
  • *****
  • Posts: 635
Re: Pointer math and (un)packed arrays
« Reply #20 on: July 09, 2019, 02:38:22 pm »
This also depends on the CPU. Many generate an exception on unaligned access.

ASerge

  • Hero Member
  • *****
  • Posts: 1392
Re: Pointer math and (un)packed arrays
« Reply #21 on: July 09, 2019, 03:49:42 pm »
...
You can comment/uncomment the ALIGN directive, the result will be the same.  "packed" in front of "array" has no effect whatsoever on, neither, the array or the elements of the array (but, it would affect the type if the type was Boolean, which seems to be the only exception and only when bitpacking is on.)
In this case, align plays a role. With {$ALIGN ON} result is 8 and 6. With {$ALIGN OFF} 6 and 6.
Again you mention bitpacked, though it's about packed. Packed array of Boolean has the same size as the packed array of Byte, the same size as the unpacked array of Byte, the same size as the length of the array. There are no exceptions:
Code: Pascal  [Select]
  1. {$APPTYPE CONSOLE}
  2. {$MODE OBJFPC} // or {$MODE FPC} or {$MODE DELPHI}
  3.  
  4. type
  5.   TPackedBoolArray = packed array[0..7] of Boolean;
  6.  
  7. begin
  8.   Writeln(SizeOf(TPackedBoolArray));
  9.   Readln;
  10. end.
Result is 8, not 1.

You say
Quote
The "packed" modifier isn't applied to the array, it's applied to the array elements
It's wrong, and I proved it.
You say
Quote
except in the case of Boolean, which seems to be the only exception
It's wrong, and I proved it.

I give you links from the documentation and an example program, and you only abstract reasoning. Maybe you just stop, read it all and quietly discard the old misconception.

And please don't talk about bitpacked again (or {$BITPACKING ON}), as I said at the beginning "Don't confused with "bitpacked".

440bx

  • Hero Member
  • *****
  • Posts: 1086
Re: Pointer math and (un)packed arrays
« Reply #22 on: July 09, 2019, 06:03:55 pm »
I give up.
using FPC v3.0.4 and Lazarus 1.8.2 on Windows 7 64bit.