cbindgen icon indicating copy to clipboard operation
cbindgen copied to clipboard

Empty Tuple-Style Enum Variants are mapped differently between C++ and C

Open TheBlueMatt opened this issue 4 years ago • 1 comments

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

TheBlueMatt avatar Apr 30 '21 18:04 TheBlueMatt

We need to check which assembly does rust generate for this, but yeah, one way or the other this is a bug.

emilio avatar Jun 15 '21 02:06 emilio