You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Often in FFI, some APIs will take *c_void or *mut c_void to indicate arbitrary objects from the caller side. When interacting with such APIs in Rust it is common to allocate something with {Box,Rc,Arc}::into_raw and then casting the raw pointer. For deallocating you often get the c_void pointer back from the FFI API and you would turn it into the corresponding owned/shared pointer with {Box,Rc,Arc}::from_raw, after which you can drop it.
However, it is easy to run into the pitfall of calling from_raw with the c_void pointer. Note that the definition of, say, Box::from_raw is:
pubunsafefnfrom_raw(raw:*mutT) -> Box<T>
meaning that if you pass a *mut c_void you will get a Box<c_void>. Per the safety requirements in the documentation, for this to be safe, c_void would need to have the same memory layout as the original type, which is often not the case. And even if it was the case, if the original type or one of its fields (or one of its fields, recursively) had a Drop implementation, that implementation would not run when this newly recreated box is dropped. (And similarly for Rc and Arc.)
While it is possible to purposefully create a Box<c_void>, it's hard to see any case where it would be useful. Therefore, uses of Box::from_raw::<c_void> can be safely assumed to be a mistake, and clippy should have a lint for it.
Lint Name
from-raw-cvoid
Category
No response
Advantage
Remove an easy pitfall of FFI, particularly with some C or C++ APIs.
Drawbacks
Might conflict with genuine usages of Box<c_void>, but those are incredibly rare, and not good practice.
Example
use std::ffi::c_void;let ptr = Box::into_raw(Box::new(42usize))as*mutc_void;// pass `ptr` through C FFI or something.let _ = unsafe{Box::from_raw(ptr)};
Could be written as:
use std::ffi::c_void;let ptr = Box::into_raw(Box::new(42usize))as*mutc_void;// pass `ptr` through C FFI or something.let _ = unsafe{Box::from_raw(ptr as*mutusize)};
The text was updated successfully, but these errors were encountered:
What it does
Often in FFI, some APIs will take
*c_void
or*mut c_void
to indicate arbitrary objects from the caller side. When interacting with such APIs in Rust it is common to allocate something with{Box,Rc,Arc}::into_raw
and then casting the raw pointer. For deallocating you often get thec_void
pointer back from the FFI API and you would turn it into the corresponding owned/shared pointer with{Box,Rc,Arc}::from_raw
, after which you can drop it.However, it is easy to run into the pitfall of calling
from_raw
with thec_void
pointer. Note that the definition of, say,Box::from_raw
is:meaning that if you pass a
*mut c_void
you will get aBox<c_void>
. Per the safety requirements in the documentation, for this to be safe,c_void
would need to have the same memory layout as the original type, which is often not the case. And even if it was the case, if the original type or one of its fields (or one of its fields, recursively) had aDrop
implementation, that implementation would not run when this newly recreated box is dropped. (And similarly forRc
andArc
.)While it is possible to purposefully create a
Box<c_void>
, it's hard to see any case where it would be useful. Therefore, uses ofBox::from_raw::<c_void>
can be safely assumed to be a mistake, and clippy should have a lint for it.Lint Name
from-raw-cvoid
Category
No response
Advantage
Drawbacks
Box<c_void>
, but those are incredibly rare, and not good practice.Example
Could be written as:
The text was updated successfully, but these errors were encountered: