I have a structure with a byte array in it. This structure actually comes from the FFI bindings produced by bindgen, and its size is defined in C code using a macro, i.e.:
C code:
#define FOO_SIZE 100
struct the_struct
{
char foo[FOO_SIZE];
/* other fields... */
};
Generated FFI bindings:
pub struct the_struct {
pub foo: [::std::os::raw::c_char; 100usize],
// other fields...
}
I want to make sure that the data coming from the Rust API side fits into foo
. I also do not want to hard code FOO_SIZE
in my Rust API, since it is subject to change.
I understand that this can be done by instantiating the struct first, but then again, that would require explicit initialization of foo
, which seems to be impossible without knowing its size. Furthermore, it is an extra step I want to avoid.
Is it possible to somehow get the size of foo
statically without instantiating the structure? If not, what would be the best approach? Changing C code is not an option.
On the nightly channel I came up with this:
#![feature(raw_ref_op)]
pub struct the_struct {
pub foo: [::std::os::raw::c_char; 100usize],
// other fields...
}
fn main() {
let foo_size: usize = {
fn size<T>(_: *const T) -> usize {
std::mem::size_of::<T>()
}
let null: *const the_struct = std::ptr::null();
size(unsafe { &raw const (*null).foo })
};
println!("{}", foo_size);
}
As far as I can tell, &raw const (*null).foo
is not UB because dereferencing a null-pointer to get another pointer is explicitly allowed. Unfortunately not only does this require the still unstable raw_ref_op
feature, but because this dereferences a pointer, this also cannot be const
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With