Closed
Description
Here's an example, lib.rs
:
#![allow(dead_code)]
#[repr(u8)]
pub enum Foo {
A {
a: u16,
b: u8,
},
B,
}
extern "C" {
fn foo() -> Foo;
}
Foo
is actually laid out as:
$ cargo rustc -- -Z print-type-sizes
Compiling foo v0.1.0 (/tmp/foo)
print-type-size type: `Foo`: 4 bytes, alignment: 2 bytes
print-type-size discriminant: 1 bytes
print-type-size variant `A`: 3 bytes
print-type-size field `.b`: 1 bytes
print-type-size field `.a`: 2 bytes
print-type-size variant `B`: 0 bytes
Finished dev [unoptimized + debuginfo] target(s) in 0.05s
...with b
and a
of the A
variant reversed. Meanwhile cbindgen
happily produces a binding with those fields in the wrong order:
$ cbindgen foo
#include <cstdint>
#include <cstdlib>
union Foo {
enum class Tag : uint8_t {
A,
B,
};
struct A_Body {
Tag tag;
uint16_t a;
uint8_t b;
};
struct {
Tag tag;
};
A_Body a;
};
extern "C" {
extern Foo foo();
} // extern "C"
A decent temporary fix would be to temporarily disable repr(int)
enums with variants containing multiple fields of different types until rustc
fixes this; if every field is the same type the ordering isn't changed. Similarly single-field variants are also fine because they can't be reordered.
Metadata
Metadata
Assignees
Labels
No labels