Binary Serialization

harakim harakim at gmail.com
Sun Jul 14 00:43:55 UTC 2019


On Sunday, 14 July 2019 at 00:18:02 UTC, Adam D. Ruppe wrote:
> On Saturday, 13 July 2019 at 23:52:38 UTC, harakim wrote:
>> class MoveCommand
>> {
>> 	byte serialNumber;
>> 	int x;
>> 	int y;
>> }
>> When I do MoveCommand.sizeof, it returns 4.
>
>
> It is important to understand a class in D is a reference type, 
> so `MoveCommand` here is actually a pointer internally, meaning 
> that 4 is the size of a pointer. Trying to directly read or 
> write that to a socket is a mistake.
>
> With struct though, there's potential. The reason you get 12 
> there though is that the byte is padded. The struct looks like
>
> 0: serialNumber
> 1: padding
> 2: padding
> 3: padding
> 4: x
> 5: x
> 6: x
> 7: x
> 8: y
> 9: y
> 10: y
> 11: y
>
>
> To get move the padding to the end, you can add `align(1):` 
> inside, so given:
>
> struct MoveCommand
> {
>   align(1):
>  	byte serialNumber;
> 	int x;
> 	int y;
> }
>
> The layout will look like this:
>
> 0: serialNumber
> 1: x
> 2: x
> 3: x
> 4: x
> 5: y
> 6: y
> 7: y
> 8: y
> 9: padding
> 10: padding
> 11: padding
>
>
> The align(1) is kinda like the __packed__ thing in C compilers. 
> The size of will still read 12 there, but you can read and 
> write an individual item direct off a binary thing reliably. 
> But an array of them will have that padding still. To get rid 
> of that, you put an align(1) on the *outside* of the struct:
>
> align(1) // this one added
> struct MoveCommand
> {
>   align(1): // in ADDITION to this one
>  	byte serialNumber;
> 	int x;
> 	int y;
> }
>
>
> And now the sizeof will read 9, with the padding cut off fromt 
> the end too. You can do an array of these now totally packed.
>
>
> This behavior is consistent across D compilers; it is defined 
> by the spec.
>
> Just remember types like `string` have a pointer embedded and 
> probably shouldn't be memcpyed!

Awesome. I kind of figured the D language would put this type of 
thing in the spec. Since the layout in memory will be consistent, 
I think I'm just going to let D do its normal thing and keep the 
members aligned in the default manner at a cost of a few extra 
bytes.

It's nice to know about align, though. In the unlikely event I 
end up running into this a lot, I will revisit that decision. I 
can just order my members for efficient space usage for now. As a 
side note, it would be cool if there were blank pages in the end 
of the The D Programming Language book to put addendums like this 
in there. I'll have to keep that in mind if I ever write a book.


More information about the Digitalmars-d-learn mailing list