Another kind of esoteric padding happens when certain fields in
entities are required to be aligned to some particular alignment. For
example, suppose that the flags
field in the packets used in
the previous sections is required to always be aligned to 4 bytes
regardless of the size of the payload. This would be a common
requirement if the format is intended to be implemented in systems
where data is to be accessed using its “natural” alignment.
Using explicit fields for both the payload and the additional padding, we could come with:
type Packet = struct { offset<uint<32>,B> payload_size; byte[payload_size] payload; byte[alignto (OFFSET, 4#B)] padding; int flags; };
Where alignto
is a little function defined in the Poke standard
library, like this:
fun alignto = (uoff64 offset, uoff64 to) uoff64: { return (to - (offset % to)) % to; }
Alternatively, using the labels approach (which is generally better as we discussed in the last section) the definition would become:
type Packet = struct { offset<uint<32>,B> payload_size;: var payload_offset = OFFSET; int flags @ OFFSET + payload_size + alignto (payload_size, 4#B); method get_payload_offset = off64: { return payload_offset; } };
In this case, the payload space is still completely characterized by
the payload_size
field and the get_payload_offset
method.