Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Documentation: Warn that byteorder types, having alignment 1, don't cause struct padding #2324

Open
Zalathar opened this issue Feb 9, 2025 · 1 comment

Comments

@Zalathar
Copy link

Zalathar commented Feb 9, 2025

The multi-byte types in zerocopy::byteorder have alignment 1, which is very useful for reading from unaligned buffers. And the documentation also shows an example of using them to assemble a larger #[repr(C)] struct, which can also be read from unaligned buffers.

However, a less-obvious consequence of alignment 1 is that a struct built from these types doesn't have the internal/trailing padding that would be present when declaring a #[repr(C)] struct made up of ordinary types like u32 or u64, which have alignment requirements.

This means that when declaring a struct to read struct data dumped by another C/Rust program, it may be necessary to manually insert padding between fields, so that the alignment 1 structure matches the actual layout of the original data.


The current behaviour is correct, of course, and is a natural consequence of the documented alignment, but could perhaps benefit from an explicit warning in the byteorder module docs.

@Zalathar
Copy link
Author

Zalathar commented Feb 9, 2025

Here's a concrete example of some code where naïvely trying to match the original C structure, without adding manual padding, would result in the wrong layout.

#[derive(FromBytes, Immutable, KnownLayout)]
#[repr(C)]
struct ProfileData<O, IntPtrT> {
    name_ref: U64<O>,
    func_hash: U64<O>,
    counter_ptr: IntPtrT,
    bitmap_ptr: IntPtrT,
    function_ptr: IntPtrT,
    values: IntPtrT,
    num_counters: U32<O>,
    num_value_sites: [U16<O>; 3],
    // We need to insert manual padding here to match the
    // actual layout of the C code that dumped this data.
    _pad: [u8; 2],
    num_bitmap_bytes: U32<O>,
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant