Skip to content

Feature request: use DST to represent structures with flexible array members #2771

@jsgf

Description

@jsgf

Input C/C++ Header

struct msg {
    unsigned int tag;
    unsigned int len;
    char payload[];
};

Bindgen Invocation

$ bindgen input.h

Actual Results

This produces an output using __IncompleteArrayField as expected:

#[repr(C)]
#[derive(Debug)]
pub struct msg {
    pub tag: ::std::os::raw::c_uint,
    pub len: ::std::os::raw::c_uint,
    pub payload: __IncompleteArrayField<::std::os::raw::c_char>,
}

Expected Results

It would be nice to have an option to model this by using a structure with a dynamic tail:

#[repr(C)]
#[derive(Debug)]
pub struct msg {
    pub tag: ::std::os::raw::c_uint,
    pub len: ::std::os::raw::c_uint,
    pub payload: [:std::os::raw::c_char],
}

These types of structures are awkward to use on their own, so it would need some helper methods:

impl msg {
    // Size and alignment so memory can be allocated
    fn layout(len: usize) -> ::std::alloc::Layout {
        unsafe {
            let p: *const Self = ::std::ptr::from_raw_parts(ptr::null(), len);
            ::std::alloc::Layout::for_value_raw(p)
        }
    }
    // Convert a raw pointer into an immutable view for a given number of payload elements.
    // Danger: Return lifetime unconstrained
    unsafe fn from_ptr<'a>(ptr: *const (), len: usize) -> &'a Self {
        let ptr: *const Self = ::std::ptr::from_raw_parts(ptr, len);
        &*ptr
    }
    // Same but mutable, and maybe uninitialized, to to allow Rust to initialize/mutate it.
    // Danger: Return lifetime unconstrained
    unsafe fn from_ptr_mut<'a>(
        ptr: *mut (),
        len: usize,
    ) -> ::std::mem::MaybeUninit<&'a mut Self> {
        let ptr: *mut Self = ::std::ptr::from_raw_parts_mut(ptr, len);
        ::std::mem::MaybeUninit::new(&mut *ptr)
    }
}

These methods would currently depend on the unstable ptr_metadata and layout_for_ptr features.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions