Types in std::os::raw should be same as libc crate
Right now, there's a bit of a discrepancy between these two, even though there shouldn't be. While the libc crate has very complicated logic to determine how the c_* types are defined, the standard library uses a much simpler logic.
I'm not sure how much these types are desired outside of libc; the only type that I've really seen used across the standard library is c_char, which honestly could just be replaced with an opaque struct with repr(u8) if it weren't already stabilised.
I feel like this issue is a duplicate, but I'm not sure.
Steve Klabnik at 2017-12-27 14:09:04
It was definitely listed in the original libc RFC as an unresolved question, and I found #36193, but I really didn't find anything that addressed this specific issue.
There are also issues regarding
c_void(rust-lang/libc#180) but that's different than this.Clar Fon at 2017-12-27 15:18:28
New RFC to propose fixing for
c_voidspecifically: https://github.com/rust-lang/rfcs/pull/2521Unlike
c_void(which is currently anenum) the rest of thec_*types aretypealiases, so two separate definitions of e.g.c_longwould be compatible in the type system as long as they agree.Are there cases where
stdandlibcdisagree on the definition of a givenc_*type for a given target?Simon Sapin at 2018-08-09 07:40:06
IMO, the fact that the code disagrees is an indication that that's probably the case. Regardless, I feel that the code for these should be the same, whether this is done by re-exporting or simply copying the code.
Clar Fon at 2018-08-09 12:42:42
To make sure the definitions never diverge I think it would be best to have them in one place, and re-export as needed. So let’s keep this issue open even if https://github.com/rust-lang/rfcs/pull/2521 is implemented.
Simon Sapin at 2018-08-09 13:01:52
I noticed that c_char is u8 in std vs i8 in libc yesterday
Hunar Roop Kahlon at 2018-08-09 13:15:46
On what target architecture? This doesn’t seem to be the case on Linux x64 at least: https://play.rust-lang.org/?gist=1bd21020fc146082988516eb1779e066&version=stable&mode=debug&edition=2015
Simon Sapin at 2018-08-09 13:42:22
A big example of a difference is
SOCKETinwinapiis different fromstddespite both being aliases to primitive numeric types, becausestdconditionally defines it asu32oru64whilewinapiunconditionally defines it asusize.Peter Atashian at 2018-08-09 14:40:17
Seemingly I was wrong... I was reading through the sources and apparently mixed up the
cfgsHunar Roop Kahlon at 2018-08-14 17:05:14
Also I seem not the odd one one out here https://users.rust-lang.org/t/crate-types-not-the-same-which-one-should-i-use/19552
Hunar Roop Kahlon at 2018-08-14 19:49:48
Genuine question: would it make sense to maybe make all of the
c_*types opaquerepr(transparent)types?This way, although they'll work in FFI as expected, Rust code has to use
FromandTryFromto actually do conversions. Additionally, theFromandTryFromcode can be tailored to only do what's valid in the C standard (e.g. assumingc_intis at least 16 bits, and no more) for portability. 99% of the time,Fromand co. will be no-ops, but it'll be required to actually do any operations on these types in Rust code.We could even do this with the inner implementation of
c_void, to mask the fact that it's an enum in its implementation. At some point we could potentially make it actually a newtype of!if we really wanted.Clar Fon at 2018-08-15 15:07:27
We can add new types like that. But changing the existing
std::os::raw::c_*andlibc::c_*types would be a breaking change.Simon Sapin at 2018-08-15 15:59:11
I think that adding new types is reasonable, if they go into
core::ffilikec_voidseems to be headed. Putting them inos::rawseems off.Clar Fon at 2018-08-15 16:35:32
These new types wouldn’t solve this issue’s problem (so they are not quite on topic), and I feel there would be enough details to figure out that they’d be worth their own RFC.
Simon Sapin at 2018-08-15 21:05:38
std::os::rawhas recently been moved tocore::ffiunder an unstable feature flag, so that may be able to solve the duplication issue betweenlibcandstdin the future (at some point in the far future whenlibcdrops support for Rust versions that doesn't have this).Tracking issue here in case you want to provide input: https://github.com/rust-lang/rust/issues/94501
Mads Marquart at 2022-06-07 16:06:01
libc currently does rustc version detection, so libc could turn these into re-exports when built on a sufficiently new rustc.
Josh Triplett at 2022-06-07 18:29:30
Do the definitions agree for all targets? As long as they do there’s no effect for users, for type aliases to primitive integers (as opposed to
c_voidwhich is defined as anenum), so choosing to reexport or not might only be a question of what makes maintenance easier. For example when adding support for a new target.Simon Sapin at 2022-06-07 18:52:04
Was going through my open issues and was wondering whether this is solved or not. The linked #94501 is merged, and I believe that the types do match now. Should this still be tracked in the standard library, or just as an issue in the libc repo?
Clar Fon at 2023-05-22 22:08:54
@joshtriplett What's the current status for this issue?
Sander Maijers at 2023-11-24 08:48:09