Skip to content

Inconsistent representation of char (constants ignore type) #1661

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

Open
dcoles opened this issue Oct 29, 2019 · 2 comments
Open

Inconsistent representation of char (constants ignore type) #1661

dcoles opened this issue Oct 29, 2019 · 2 comments

Comments

@dcoles
Copy link

dcoles commented Oct 29, 2019

On my platform char is signed, thus trying to assign a char-string constant (which becomes &[u8, _] in Rust) to a char * field in a struct results in a mismatched types error.

This one was a little surprising, but is understandable given C's fuzzyness around what a char is.
I could understand closing this as WONTFIX due to the likely breakage such a change would cause (as well as the annoyance of working with std::os::raw::c_char), but would at least be useful to add to the FAQ.

Alternatively there could be some sort of flag to bindgen control this behaviour.

Input C/C++ Header

struct my_struct {
    const char *str;
    const unsigned char *ustr;
    const signed char *sstr;
};

static const char STR[] = "Hi!";
static const signed char USTR[] = "Hi!";
static const unsigned char SSTR[] = "Hi!";

Bindgen Invocation

$ bindgen input.h --no-layout-tests

Actual Results

/* automatically generated by rust-bindgen */

#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct my_struct {
    pub str: *const ::std::os::raw::c_char,
    pub ustr: *const ::std::os::raw::c_uchar,
    pub sstr: *const ::std::os::raw::c_schar,
}
pub const STR: &'static [u8; 4usize] = b"Hi!\0";
pub const USTR: &'static [u8; 4usize] = b"Hi!\0";
pub const SSTR: &'static [u8; 4usize] = b"Hi!\0";

Expected Results

This one kinda sucks because char can be either signed or unsigned (and technically doesn't even have to be 8-bits). Here's a version that strictly preserves the types:

/* automatically generated by rust-bindgen */

#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct my_struct {
    pub str: *const ::std::os::raw::c_char,
    pub ustr: *const ::std::os::raw::c_uchar,
    pub sstr: *const ::std::os::raw::c_schar,
}
const STR: &'static [::std::os::raw::c_char; 4] = &[72, 105, 33, 0];
const USTR: &'static [::std::os::raw::c_uchar; 4] = &[72, 105, 33, 0];
const SSTR: &'static [::std::os::raw::c_schar; 4] = &[72, 105, 33, 0];
@dcoles
Copy link
Author

dcoles commented Oct 29, 2019

I would also be willing to have a go at writing said FAQ entry if it would be helpful.

@emilio
Copy link
Contributor

emilio commented Oct 31, 2019

I think this is also related to #1401... I think there are use-cases that benefit from the current behavior (mostly, interacting with the core::ffi stuff), and others that would benefit from keeping the exact type (like adding members to a struct).

We could add a flag of sorts, if wanted, but an entry in the FAQ until that happens would definitely be amazing!

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

2 participants