Size of type WITHOUT alignment padding


I’m writing some code which allocates a series of items into a contiguous region of memory, all of different types and sizes, something like: [val1: u32, val2: u8, etc].

Currently, the code looks something like this pseduocode:

block: *mut u8;
offset: isize;

for some_type in my_types {
    offset = round_up_to(offset, std::mem::align_of<some_type>());
    obj_ptr = block.offset(offset);

    // pointless padding space here!!!
    offset + std::mem::size_of::<some_type>();

My issue is that size_of::() not only returns the size of the type, but also padding to properly align what would be another of the same type afterwards in memory. I don’t want to do that - I already manage the alignment myself, and don’t want to waste space on pointless padding. For example, If I have a struct which requires 4 bytes of padding, followed by a struct which only requires 4 bytes of alignment, I want to start the next struct immediately instead of having 4 bytes of padding.

Unfortunately, code like:

struct get_raw_size_of<T> {
    single_elem: T,

does not work, as the padding of single_elem is included anyways in the packed struct. Packing the original structs is also out of the question for me.

Is there a way to do this in stable rust?



If you don’t pack the original, then any writes to that struct may also clobber the padding area. I suspect that your intended use of that padding would be Undefined Behavior.



Looking at the compiler, it appears that this information is not exposed from the compiler.

@cuviper you’re probably correct, the compiler may well write to this padding for any purpose if it deems it an optimization (using a 16-byte write over a series of smaller ones), which is unfortunate. This isn’t currently done, but I can’t find anything about whether it’s allowed.

A representation without padding at the end would be difficult for a whole slew of reasons, but it would be useful to access that information and tell the compiler not to use that padding.



It actually coalesces writes into one if you add one more field! Perhaps the cost of unaligned store is greater than cost of two writes, but smaller than three.



This seems roughly the same as what wants/proposes.

1 Like