Thanks Alex -
But I have to respectfully disagree - 'struct' should know
that if its current offset is 10, and it next needs to layout
a 4-byte integer, it should insert 2 pad bytes to begin
the integer at offset 12 - the same as it should know
in the 'struct tm' case, that if it has just laid out a 4-byte integer
at offset 32, ending at offset 36, and next needs to layout an 8-byte
integer, it needs to insert 4 pad bytes to start the 8-byte integer
at offset 40 .
'struct' is documented as honoring C structure layout rules:
"Creates or extracts data structures, suitable to be passed
to or returned from native C functions.
"
But it does not do what it claims , because it does not
insert the required pad bytes - it lays everything out as
if the programmer had specified '#pragma packed' or
'__attribute__((packed))' for the whole structure.
In future versions, there ought to be a way of telling
struct to use packed alignment (not insert pad bytes),
or to use custom alignment ( the 2nd 'size' cdr of
the result spec cons cells could be specified as a
cons cell of Size and Alignment ).
Really, it is not nice to make programmers have to take account
of these pad bytes, which they do not have to do using "C" -
on extract, they'd have to remember which pad members
they had to insert and filter them out - they are not proper
"members" of the structure - this will lead to much
confusion and coredumps / unexpected behaviour when C functions
receive structures without required pad bytes.
And making the programmer change the datatype of members,
as you suggested, is not a solution either - pad bytes must be
IGNORED, there is no guarantee they are initialized to 0, if
malloc() was used to allocate the structure, they may have
garbage values, so if we transformed the 'short' into an 'int',
or the 'int' into a 'long' , to satisfy padding requirements,
then likely as not garbage values for these members would be
extracted.
I will try to produce a version of PicoLisp whose 'struct DOES
insert these missing pad bytes, and see if I can make it
pass all tests, and if so I'll send you the patch - hopefully by
the end of this week.
Best Regards,
Jason
On 06/12/2021, Alexander Burger <[email protected]> wrote:
> On Mon, Dec 06, 2021 at 11:21:27PM +0100, Alexander Burger wrote:
>> No, it is correct. It stores (all little-endian):
>>
>> (1 . 8) 1 0 0 0 0 0 0 0 # 8 bytes
>> (2 . 2) 2 0 # 2 bytes
>> (3 . 4) 3 0 0 0 # 4 bytes
>
> The point is: 'struct' does exactly what you tell it to do. Not more, not
> less.
> Eight bytes, then two bytes, then four bytes.
>
> It does not care (and should not care) that *you* know that the "short"
> should
> be in a wider field. This is another, higher level. Here we are purely
> concerned
> about the explicat layout.
>
> You can easily pass
>
> : (struct Ptr '( P W I ) '(1 . 8) '(2 . 4) '(3 . 4))
>
> to get what you want.
>
> ☺/ A!ex
>
> --
> UNSUBSCRIBE: mailto:[email protected]?subject=Unsubscribe
>
--
UNSUBSCRIBE: mailto:[email protected]?subject=Unsubscribe