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

string::raw::from_buf and c_char conflict #16283

Closed
metajack opened this issue Aug 5, 2014 · 8 comments
Closed

string::raw::from_buf and c_char conflict #16283

metajack opened this issue Aug 5, 2014 · 8 comments

Comments

@metajack
Copy link
Contributor

metajack commented Aug 5, 2014

c_char is i8, so trying to use string::raw::from_buf involves this:

let cstring: *c_char = .....;
let s = string::raw::from_buf(cstring as *const i8 as *const u8);

Either c_char should switch to u8, or string::raw::from_buf should take *const i8. Right now using this is quite tedious.

@metajack
Copy link
Contributor Author

metajack commented Aug 5, 2014

cc @aturon

@aturon
Copy link
Member

aturon commented Aug 5, 2014

Thanks for the heads up, I'll take care of this.

@huonw
Copy link
Member

huonw commented Aug 6, 2014

Theoretically cstring as *const u8 should work directly?

I believe c_char is attempting to match what the platform's C compiler's do w.r.t. the signedness of chars. I think we should possibly just 'focus' these concerns into CString rather than duplicating the null-termination handling everywhere, something like CString::new(x, false).as_str().unwrap().to_string() (which is a little verbose), shrug

@metajack
Copy link
Contributor Author

metajack commented Aug 6, 2014

My preference is to make c_char a u8. I believe @zwarich expressed a similar opinion.

@huonw It's possible the examples I'm running into start from &c_char or something. There are a few examples of this in the latest Rust upgrade:
servo/servo@6f667d0#diff-d41d8cd98f00b204e9800998ecf8427e

@zwarich
Copy link

zwarich commented Aug 6, 2014

@huonw If we tried to match the platform C compilers means then c_char would be a different type on different platforms, and even different ABIs on the same architecture. For example, ARM's ABIs have unsigned char, whereas Apple's ABIs all have signed char. This isn't so bad in portable C because of the implicit numeric conversions (which are bad for other reasons), but it wouldn't work in Rust. I don't see a good reason to not make it u8.

@zwarich
Copy link

zwarich commented Aug 6, 2014

It seems that x86_64 compilers like Clang expect a char to be sign-extended in its register, even though I can't find this in the official ABI spec.

@mahkoh
Copy link
Contributor

mahkoh commented Aug 7, 2014

c_char not being char will break sign extension in FFI code:

void f(int);

int main(void) {
    char c = -1;
    f(c);
}
fn main() {
    let c: c_char = -1;
    unsafe { f(c as c_int); }
}

On the same machine this will do different things if the signedness of c_char and the signedness of char don't match.

@alexcrichton
Copy link
Member

This was resolved in #20507

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants