This code works fine but gives a compiler warning on Rust nightly (1.2)
#[repr(C)]
struct DbaxCell {
cell: *const c_void
}
#[link(name="CDbax", kind="dylib")]
extern {
fn new_dCell(d: c_double) -> *const c_void;
fn deleteCell(c: *const c_void);
}
impl DbaxCell {
fn new(x: f64) -> DbaxCell {
unsafe {
DbaxCell { cell: new_dCell(x) }
}
}
}
impl Drop for DbaxCell {
fn drop(&mut self) {
unsafe {
deleteCell(self.cell);
}
}
}
It links to a C library and creates/deletes cell objects correctly. However it gives a warning
src\lib.rs:27:1: 33:2 warning: implementing Drop adds hidden state to types, possibly conflicting with `#[repr(C)]`, #[warn(drop_with_repr_extern)] on by default
\src\lib.rs:27 impl Drop for DbaxCell {
\src\lib.rs:28 fn drop(&mut self) {
\src\lib.rs:29 unsafe {
\src\lib.rs:30 deleteCell(self.cell);
\src\lib.rs:31 }
\src\lib.rs:32 }
What is the right way to do this to ensure that these DbaxCell
s are cleaned up correctly and no warning is given?
I think you are conflating two concepts. A struct should be
repr(C)
if you wish for the layout of the struct to directly correspond to the layout of the struct as a C compiler would lay it out. That is, it has the same in-memoryrepr
esentation.However, you don't need that if you are just holding a raw pointer, and are not going to pass the holding structure back to C. The short solution in this case is "remove
repr(C)
".To explain a bit more about the error...
This was discussed in issue 24585. When an object is dropped, a hidden flag (the "state") is set that indicates that the object has been dropped, preventing multiple drops from occurring. However, hidden bits mean that what you see in Rust does not correspond to what the bytes of the struct would look like in C, negating the purpose of the
repr(C)
.As cribbed from @bluss:
And
Imagine we had a library that exposes a C struct with two 8-bit numbers, and methods that take and return that struct:
In this case, you would definitely want to mimic that struct and match the C representation in Rust:
However, if the library returned pointers to the struct, and you never need to poke into it (the structure is opaque) then you don't need to worry about
repr(C)
:Then you can just use that pointer and implement Drop: