rust-lang / nomicon

The Dark Arts of Advanced and Unsafe Rust Programming
https://doc.rust-lang.org/nomicon/
Apache License 2.0
1.75k stars 258 forks source link

Can we use non_exhausive attr instead of zero length array in "Representing Opaque Structs" #342

Open Havvy opened 2 years ago

Havvy commented 2 years ago

Section: https://doc.rust-lang.org/nomicon/ffi.html#representing-opaque-structs

Currently, it uses a struct like this:

#[repr(C)]
pub struct Foo {
    _data: [u8; 0],
    _marker:
        core::marker::PhantomData<(*mut u8, core::marker::PhantomPinned)>,
}

But since that was written, we have access to the #[non_exhausive] attribute. I think it has the same functionality. Any reason we shouldn't be suggesting this instead?

#[repr(C)]
#[non_exhaustive]
pub struct Foo {
    _marker:
        core::marker::PhantomData<(*mut u8, core::marker::PhantomPinned)>,
}
JohnTitor commented 2 years ago

I guess it's just not updated (we have a lot of outdated content!), I'm happy to see a PR :)

reisnera commented 1 year ago

Is there a benefit to adding #[non_exhaustive] or even having the _data member at all? PhantomData itself is a ZST no? Also I feel like you could just as well use () rather than u8 for the pointer just to further remove any suggestion that this is anything other than a trick to make an opaque FFI type. I might be missing something but wouldn't the following be just as good?

#[repr(C)]
pub struct Foo {
    _marker: core::marker::PhantomData<(*mut (), core::marker::PhantomPinned)>,
}
FeldrinH commented 1 month ago

I might be missing something but wouldn't the following be just as good?

#[repr(C)]
pub struct Foo {
    _marker: core::marker::PhantomData<(*mut (), core::marker::PhantomPinned)>,
}

I was reading that section and had the exact same question. If the [u8; 0] is indeed necessary for something then it would be good to clarify in the book what benefit it provides.