Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move std::os::raw to libcore? #36193

Closed
SimonSapin opened this issue Sep 1, 2016 · 21 comments
Closed

Move std::os::raw to libcore? #36193

SimonSapin opened this issue Sep 1, 2016 · 21 comments
Labels
C-enhancement Category: An issue proposing an enhancement or a PR with one. T-libs-api Relevant to the library API team, which will review and decide on the PR/issue.

Comments

@SimonSapin
Copy link
Contributor

I’m currently playing "embedded" with hardware (ARM Cortex-M CPU with 64 KB RAM). I’m using #![no_std] (there’s no operating system) and FFI to use C and C++ device drivers.

For bindings I’d like to use std::os::raw::c_long and other types in that module. But this module is not available in libcore. Is there a reason for this? If not, I’ll submit a PR to move it (and of course re-export it at its current location).

@steveklabnik steveklabnik added A-libs T-libs-api Relevant to the library API team, which will review and decide on the PR/issue. labels Sep 1, 2016
@steveklabnik
Copy link
Member

Historically, my understanding is that libcore is not supposed to contain anything os-specific. I think.

@SimonSapin
Copy link
Contributor Author

My understanding is that it doesn’t depend on API or other things provided at run-time by an OS, but that doesn’t mean it can’t have things that compile differently based on the target/platform. src/libcore already contains cfg attributes or macros for:

  • target_pointer_width
  • target_arch
  • sse2
  • target_endian
  • target_has_atomic

@alexcrichton
Copy link
Member

Yes historically we have not done this because of what @steveklabnik said. These types are OS-specific, not architecture specific, which I believe the other flags you're mentioning @SimonSapin are.

This is also why the libc crate has a #![no_std] mode, for using these types without libstd.

@SimonSapin
Copy link
Contributor Author

This is also why the libc crate has a #![no_std] mode, for using these types without libstd.

Ohh, I didn’t know about that. Thanks!

@SimonSapin
Copy link
Contributor Author

SimonSapin commented Sep 1, 2016

Well, current libc doesn’t build on a custom thumbv7em-none-eabi target. (4 thousands and some lines of compile errors: rust-lang/libc#375)

Regardless, I don’t understand why having cfg(windows) conditional compilation in libcore is so much worse than cfg(sse2), long as libcore doesn’t run-time-depend on things from the OS.

@retep998
Copy link
Member

retep998 commented Sep 2, 2016

Regarding #[cfg(windows)], winapi defines the C types itself https://github.com/retep998/winapi-rs/blob/dev/src/lib.rs#L35. It only relies on std for c_void if that feature is enabled.

I personally don't hold an opinion either way on whether this sort of stuff should be in libcore. If it does get added to libcore, just be very careful to ensure that they are defined correctly for every single obscure platform that libcore can be used on.

@parched
Copy link
Contributor

parched commented Sep 8, 2016

These are target specific, not OS specific aren't they? And there's other target specific stuff in core, isn't there? I think it would be useful to interface easily with C using no_std.

@Amanieu
Copy link
Member

Amanieu commented Sep 8, 2016

Not exactly. For example on x86_64, c_long is 32 bits on Windows and 64 bits everywhere else.

@Amanieu
Copy link
Member

Amanieu commented Sep 8, 2016

Moving these types into core without breaking compatibility with the libc crate (especially for the c_void type) is going to be challenging. I think a better solution would be to move them into a separate no_std crate called ctypes (name subject to the usual bikeshedding). Unlike libc, ctypes does not link to the C library and only provides type definitions and constants. The libc crate will then be modified to re-export the types from ctypes.

@parched
Copy link
Contributor

parched commented Sep 8, 2016

Not exactly. For example on x86_64, c_long is 32 bits on Windows and 64 bits everywhere else.

Yes, but I would say it's because they are different "targets" or ABIs. It's not like they are consistent on an OS, i.e., c_long isn't always 32 bits on Linux irrespective of the target.

@bluss
Copy link
Member

bluss commented Sep 10, 2016

@Mark-Simulacrum Mark-Simulacrum added the C-enhancement Category: An issue proposing an enhancement or a PR with one. label Jul 26, 2017
@gnzlbg
Copy link
Contributor

gnzlbg commented Nov 16, 2017

I think that if:

  • std::os::raw would be gated on platforms, and
  • core crates wouldn't need a solution to this problem,

the status quo would make sense.

But is std::os::raw gated on anything? If not, the moment LLVM adds support for a new platform the std::os::raw::* types becomes automatically stable for that platform in the next release, because from that point on changing any of it is a breaking change.

Also, calling C code is not uncommon for #[no_std] core-only crates, and compiling a core crate still requires a target triple (or target description) which the definitions of void* and long must match.

Furthermore, a couple of SIMD intrinsics are specified with c_void in stdsimd:

  • fn _mm_prefetch(p: *const c_void, strategy: i8)
  • fn _mm_clflush(p: *mut c_void)

Maybe we should change that, but right now it means that core::vendor requires std 🤣

@Amanieu
Copy link
Member

Amanieu commented Nov 16, 2017

I've been using the cty crate to get C types in no_std environments, but this really should be part of libcore. The main issue with cty is that its c_void is not compatible with the one from libc.

@gnzlbg
Copy link
Contributor

gnzlbg commented Nov 16, 2017

Could expose cty in core as core::ctypes, and then use it in std::os::raw and libc to make all types be equal? That way we would be able to use them in core, and we wouldn't need to do the dance of converting os::raw::c_void to libc's c_void and vice-versa. pinging @japaric

@SimonSapin
Copy link
Contributor Author

These types are OS-specific, not architecture specific, which I believe the other flags you're mentioning @SimonSapin are.

Although it’s in an internal implementation detail rather than in a public API, libcore now has:

    #[cfg_attr(not(any(target_os = "emscripten", target_os = "redox",
                       target_endian = "big")),
               repr(simd))]
    struct Block(u64, u64, u64, u64);

which does depend on the OS.

Anyway, I still don’t understand why this distinction is useful. Compiled libcore is distributed together with libstd, in "targets" that are both OS-specific and architecture specific. #[cfg(target_os = "…")] is available to libcore just as well as other cfgs.

@SimonSapin
Copy link
Contributor Author

New RFC to propose this more formally, but only for c_void for now: rust-lang/rfcs#2521

@lygstate
Copy link
Contributor

I've been using the cty crate to get C types in no_std environments, but this really should be part of libcore. The main issue with cty is that its c_void is not compatible with the one from libc.

I like you idea, the ctypes and some basic type should be in a non_std crate and distribute with rust.
We can stablize it day but, doesn't need to be in a single short.

@lygstate
Copy link
Contributor

Merge cty into core named with ctype?

@lygstate
Copy link
Contributor

Also, cty lost these type:

The C99 standard introduces the following datatypes. The documentation can be found here for the AVR stdint library.

uint8_t means it's an 8-bit unsigned type.
uint_fast8_t means it's the fastest unsigned int with at least 8 bits.
uint_least8_t means it's an unsigned int with at least 8 bits.
I understand uint8_t and what is uint_fast8_t( I don't know how it's implemented in register level).

1.Can you explain what is the meaning of "it's an unsigned int with at least 8 bits"?

2.How uint_fast8_t and uint_least8_t help increase efficiency/code space compared to the uint8_t?

@madsmtm
Copy link
Contributor

madsmtm commented Jun 7, 2022

This has recently been implemented as an unstable feature, tracking issue here: #94501

@Amanieu
Copy link
Member

Amanieu commented Jun 7, 2022

Closing in favor of the tracking issue.

@Amanieu Amanieu closed this as completed Jun 7, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-enhancement Category: An issue proposing an enhancement or a PR with one. T-libs-api Relevant to the library API team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests