cbindgen
cbindgen copied to clipboard
Empty Tuple-Style Enum Variants are mapped differently between C++ and C
A tuple like the following:
#[repr(C)]
pub enum A {
VarA(),
VarB(u8),
}
is mapped differently in C and C++ due to the fact that C and C++ empty structs have different sizes. Both use an empty struct to represent VarA, which is different across the languages (and even breaks if you import the C header with extern "C"). It seems easiest to simply drop the body mapping for VarA.
eg C can be
typedef enum A_Tag {
A_VarA,
A_VarB,
A_Sentinel,
} A_Tag;
typedef struct A_VarA_Body {
} A_VarA_Body;
typedef struct MUST_USE_STRUCT A {
A_Tag tag;
union {
A_VarA_Body var_a;
struct {
uint8_t var_b;
};
};
} A;
with C++
struct MUST_USE_STRUCT A {
enum class MUST_USE_ENUM Tag {
A_VarA,
A_VarB,
A_Sentinel,
};
struct A_VarA_Body {
};
struct A_VarB_Body {
uint8_t _0;
};
Tag tag;
union {
A_VarA_Body var_a;
A_VarB_Body var_b;
};
};
We need to check which assembly does rust generate for this, but yeah, one way or the other this is a bug.