Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

295
Visualizações
Correct idiom for freeing repr(C) structs using Drop trait

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 DbaxCells are cleaned up correctly and no warning is given?

over 4 years ago · Santiago Trujillo
1 Respostas
Responde à pergunta

0

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-memory representation.

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...

implementing Drop adds hidden state to types, possibly conflicting with #[repr(C)]

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:

Low level programmers, don't worry: future Rust will remove this drop flag entirely.

And

Use repr(C) to pass structs in FFI, and use Drop on "regular Rust" structs if you need to. If you need both, embed the repr(C) struct inside the regular struct.

Imagine we had a library that exposes a C struct with two 8-bit numbers, and methods that take and return that struct:

typedef struct {
    char a;
    char b;
} tuple_t;

tuple_t tuple_increment(tuple_t position);

In this case, you would definitely want to mimic that struct and match the C representation in Rust:

#[repr(C)]
struct Tuple {
    a: libc::char,
    b: libc::char,
}

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):

void tuple_increment(tuple_t *position);

Then you can just use that pointer and implement Drop:

struct TuplePointer(*mut libc::c_void);

impl Drop for TuplePointer {
    // Call the appropriate free function from the library
}
over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda