rust-lang / rust-lang/rust-bindgen

Inconsistent representation of char (constants ignore type)

Open
#1,661 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Rust
Stars
5.3k
Forks
829
Avg merge
1d 1h
Merged PRs (30d)
15

Description

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];

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reproducing the issue with input.h and bindgen input.h --no-layout-tests, then inspect how the generated constants represent char, signed char, and unsigned char. Compare the output with the type-preserving expected results. Done means either preserving the declared character types or documenting the limitation in the FAQ, with any proposed option clearly defined.

Written by the indexing model from the issue text.

Assessment

Tech stack
c, cpp, rust
Domain
tooling
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.