Skip to content

C++20 enum class : char8_t enumerators are signed i8 (-1 instead of 255) #3464

Description

@lwz23

Input C/C++ Header

enum class E : char8_t { HEX = u8'\xFF', A = u8'A' };
enum class U : unsigned char { HEX = 255 };
int takeE(E e, int t);
int takeU(U e, int t);
unsigned sz(void);

Bindgen Invocation

$ bindgen input.h --no-rustfmt-bindings --enable-cxx-namespaces -- -x c++ -std=c++20

Actual Results

char8_t is unsigned in C++20. A char8_t parameter is already u8. enum class : unsigned char with value 255 is 255 / c_uchar on both sides.

Only enum underlying char8_t is signed:

pub const E_HEX: E = -1;
pub const E_A: E = 65;
pub type E = i8;
pub const U_HEX: U = 255;
pub type U = ::std::os::raw::c_uchar;

C++ (int)E::HEX is 255. Rust E_HEX as i32 is -1. sizeof is 1 on both sides. bindgen exit 0, rustc exit 0.

takeE(E::HEX, 10) is 265 on both sides (the callee still sees bits 0xFF). The generated constant is the silent C-to-Rust meaning error.

libclang has no CXType_Char8; char8_t is CXType_Unexposed. clang_getEnumConstantDeclUnsignedValue for HEX is already 255; bindgen takes the signed API because Enum::from_ty defaults is_signed = true when the Unexposed underlying type does not resolve to an Int. build_builtin_ty already maps CXType_Char16u16 and CXType_Char32u32.

This is not #2475 (unicode character macros failing to parse).

Expected Results

enum class : char8_t should be an unsigned 8-bit type, with E_HEX = 255, matching C++ and matching how bindgen already treats char16_t / char32_t / unsigned char.

Environment

bindgen current main: 77cbc72
bindgen:              0.73.1
clang:                Apple clang 21.0.0
rustc:                1.97.1
target:               aarch64-apple-darwin

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions