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 <a...@software-lab.de> 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:picolisp@software-lab.de?subject=Unsubscribe > -- UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe