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

Eliminate uses of C types in std #7313

Closed
brson opened this issue Jun 22, 2013 · 6 comments
Closed

Eliminate uses of C types in std #7313

brson opened this issue Jun 22, 2013 · 6 comments
Labels
A-FFI Area: Foreign function interface (FFI) C-cleanup Category: PRs that clean code up or issues documenting cleanup. E-easy Call for participation: Easy difficulty. Experience needed to fix: Not much. Good first issue.

Comments

@brson
Copy link
Contributor

brson commented Jun 22, 2013

There is a lot of runtime code in std that, for various reasons, uses C types instead of Rust types. Let's push all those C types down to the FFI layer and stop using them for other purposes.

@gavinb
Copy link
Contributor

gavinb commented Jun 24, 2013

Hi @brson, just to clarify the scope of this change...

Is this only to change the use of libc types in the interfaces published by modules in libstd, but to leave implementation details that use types such as c_int and c_size_t? Or should it be virtually a global replacement, with no use of libc types outside of libc itself?

What about in the external declarations of libc functions - which style should be used, as per an example in cmath?

unsafe fn acos(n: c_double) -> c_double;
unsafe fn acos(n: f64) -> f64;

IOW if we can be certain that the usage of a c_int is consistently defined on each supported arch/os, should i32 be substituted globally?

@brson
Copy link
Contributor Author

brson commented Jun 24, 2013

The general guideline I suggest is that extern fns should use C types to match the C code, but Rust functions shouldn't. As one example, some of the lang items - the interface between the compiler and the library - in unstable::lang are defined in terms of C types, not Rust types.

@gavinb
Copy link
Contributor

gavinb commented Jun 26, 2013

Thanks, @brson. I performed a little analysis of the libc types used in libstd and found the following:

type            frequency
c_void          306
c_int           264
c_char          126
size_t          119
c_double        113
c_float         101
FILE            55
intptr_t        48
uintptr_t       44
pid_t           10
DIR             5
ssize_t         4
dirent_t        4
c_uchar         4
mode_t          3
c_long          3
c_ulong         1

The type c_void seems to be used mainly as a generic pointer. I could either change these to *u8, or define a new generic bufptr type (in lang or sys?) to use instead.

The c_char type is frequently used for heap pointers, and should probably be replaced with *u8. Similarly, when used for strings, I think this usage should be replaced with *u8 to be consistent with the str type being a [u8]. So there's probably little call for *i8 any more, and I think existing usage of such should be changed to *u8 for consistency.

The c_double and c_float are overwhelmingly used in the extern declarations in cmath and the like, so there will be few changes there, if any.

The intptr_t and uintptr_t can be replaced with uint and int respectively. And size_t can become uint.

After having a stab at changing things piecemeal and then discovering inconsistencies lurking in every corner (eg. strings sometimes being c_char and sometimes *i8), I thought I should step back and analyse it properly first.

So, how does that sound as a plan of attack?

@pcwalton
Copy link
Contributor

@gavinb Sounds good.

@bstrie
Copy link
Contributor

bstrie commented Oct 17, 2013

Is our std::util::Void type a drop-in replacement for c_void?

@thestinger
Copy link
Contributor

@bstrie: yeah, they're both just uninhabited enums, although neither compiles to the LLVM type that's expected for void

bors added a commit that referenced this issue Jan 22, 2014
…richton

I've started working on a patch for #7313 . So far I tried to replace C types in `src/libstd/unstable/*` and related files.

So far, I have two questions. Is there a convention for passing pointers around in `std` as Rust types? Sometimes pointers are passed around as `*c_char` (which seems to be an `*i8`), `*c_void` or `*u8`, which leads to a lot of casts. E.g: [`exchange_malloc`](https://github.com/fhahn/rust/compare/issue-7313-replace-c-types?expand=1#diff-39f44b8c3f4496abab854b3425ac1617R60) used to return a `*c_char` but the function in turn only calls `malloc_raw` which returns a `*c_void`.
Is there a specific reason for this?

The second question is about `CString` and related functions like `with_c_str`. At the moment these functions use `*c_char*`. Should I replace it with `*u8` or keep it, because it's an wrapper around classical C strings?
@bors bors closed this as completed in 2eb4f05 Jan 22, 2014
flip1995 pushed a commit to flip1995/rust that referenced this issue Jun 3, 2021
Rustup

Empty rustup. No changes to Clippy in the Rust repo for the last 2 weeks 😮

changelog: none
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-FFI Area: Foreign function interface (FFI) C-cleanup Category: PRs that clean code up or issues documenting cleanup. E-easy Call for participation: Easy difficulty. Experience needed to fix: Not much. Good first issue.
Projects
None yet
Development

No branches or pull requests

5 participants