📝Rust, variable-length arrays in structs

Rust allows variable-length arrays as the last field in struct:

struct Symbol {
    hash: u64,
    name: [u8],
}

However, this makes structure unsized (!Sized) and pointers to unsized types are fat pointers—they contain a pointer + a size. Therefore, these pointers are bad for interop with C.

A possible trick is to define the last field as 0-sized array:

// Don't forget repr(C) as otherwise
// the compiler can reorder the fields!
#[repr(C)]
struct Symbol {
    hash: u64,
    name: [u8; 0],
}

Then you have to use unsafe casts and manual memory allocation, carefully to avoid moves. This is obviously unsafe and cumbersome but sometimes you have to do that anyway. In that case, 0-length array is still better than dropping the last field and doing risky pointer arithmetic to access the bytes after struct. At least it handles alignment.

Backlinks

Want to receive my 🖋 posts as I publish them?