- Feature Name:
c_void_reunification
- Start Date: 2018-08-02
- RFC PR: rust-lang/rfcs#2521
- Rust Issue: rust-lang/rust#53856
Summary
Unify std::os::raw::c_void
and libc::c_void
by making them both re-exports of a definition
Motivation
std::os::raw::c_void
and libc::c_void
are different types:
There is no good reason for this, the program above should compile.
Note that having separate definitionsc_*
types since they are type
aliases.c_int
is i32
for example, and separate aliasesc_void
however is currently definedenum
(of size 1 byte, with semi-private variants), and two enum
types with identical
This has been extensively discussed already:
- Issue #31536: std
c_void
and libcc_void
are different types - Internals #3268: Solve
std::os::raw::c_void
- Issue #36193: Move std::os::raw to libcore?
- RFC #1783: Create a separate libc_types crate for basic C types
- Issue #47027: Types in std::os::raw should be same as libc crate
- Internals #8086: Duplicate std::os::raw in core?
- PR #52839: Move std::os::raw into core
Guide-level explanation
With this RFC implementedlibc
crate, std::os::raw::c_void
and libc::c_void
are now two ways to name the same type.
If two independent libraries both providevoid*
pointers, one might use std
while the other uses libc
to access the c_void
type in order*mut c_void
in their respectiveas
pointer cast.
#![no_std]
crates can now also access that same type at core::ffi::c_void
.
Reference-level explanation
In the standard library:
- Create a new
core::ffi
module. - Move the
enum
definiton ofc_void
there. - In
c_void
’s former location (std::os::raw
), replace it with apub use
reexport. - For consistency between
core
andstd
, also add a similar似ている、同様のpub use
reexport atstd::ffi::c_void
. (Note that thestd::ffi
module already exists.)
Once the above lands in Nightly, in the libc
crate:
- Add a build script that detects the existence of
core::ffi::c_void
(for example by executing実行(する)$RUSTC
with a temporary一時的なfile like#![crate_type = "lib"] #![no_std] pub use core::ffi::c_void;
) and conditionally setセットする、集合a compilation flag for the library. - In the library, based基となる、基底(の)on the precence of that flag, make
c_void
be eitherpub use core::ffi::c_void;
or its currentenum
definition,定義to keep compatibility互換性with older Rust versions.
Drawbacks
This proposal is a breaking change for users who implement
With the two c_void
types being unified, the two impl
s would overlap
Hopefully such breakage is rare
-
Adding
たすsupport to Crater if it doesn’t have it already for addingたすa[patch.crates-io]
section節to each rootCargo.toml
being tested, in order順序to test with a patchedlibc
crate in addition追加to a patched Rust. -
Or speculatively landing the changes in
libc
and publishing them in crates.io before landing them in Rust
Rationale and alternatives代わりのもの、選択肢
libc
cannot reexport std::os::raw::c_void
because this would regress compatibility#![no_std]
.
RFC #1783 proposed addingstd
and libc
would depend on this crate.
This was apparently in response to reluctance about having operating-system-dependant definitionsc_long
) in libcore. This concern does not applyc_void
, whose definition
That RFC was closed / postponed with this explanation:
The current consensus is to offer a canonical way of producing
産出、産出するan "unknown, opaque type" (a better c_void), possible along the lines of #1861
RFC 1861 for extern
types is now being implemented,!Sized
. Changing c_void
from Sized
to !Sized
would be a significant breaking change: for example, ptr::null::<c_void>()
and <*mut c_void>::offset(n)
would not be usable anymore.
We could deprecated c_void
and replace it with a new differently-named extern type, but forcing the ecosystem through that transition seems too costly for this theoretical nicety. Plus, this woud still be a nominal type. If this new type is to be presentlibc
and std
, it would still have to be in core
as well.
Unresolved questions
What is the appropriate location for c_void
in libcore?
This RFC proposes core::ffi
rather than core::os::raw
on the basis that C-compatible types are misplaced in std::os::raw
. std::os
is documentedstd::os::raw
is about interoperabily with C rather than operating system functionality. (Although the exact definitionc_char
, c_long
, and c_ulong
does vary basedffi
module seems more appropriate than os
for C types, and it already exists in std
.
Followingstd::os::raw
should also move to std::ffi
as well, and the former module be deprecated eventually. This is left for a future RFC.
This RFC does not propose any change such as moving to libcore for the C types other than c_void
.
Although some in previouslibc
crate does) or depending on std
. This use case is also left for a future proposal or RFC.