Skip to content

Commit 44c79c8

Browse files
committed
fix field-less repr(C) enum docs
1 parent 7d03395 commit 44c79c8

File tree

1 file changed

+11
-6
lines changed

1 file changed

+11
-6
lines changed

src/type-layout.md

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -344,11 +344,15 @@ assert_eq!(std::mem::align_of::<SizeRoundedUp>(), 4); // From a
344344
r[layout.repr.c.enum]
345345
#### `#[repr(C)]` Field-less Enums
346346

347-
For [field-less enums], the `C` representation has the size and alignment of
348-
the default `enum` size and alignment for the target platform's C ABI.
347+
For [field-less enums], the `C` representation requires the discriminant values to
348+
be representable by the `int` type in the target platform's C ABI.
349+
Nevertheless, the type of the discriminant is `isize`.
350+
The size and alignment of the enum then match that of a C enum with the same
351+
discriminant values (and without a fixed underlying type).
349352

350353
> [!NOTE]
351354
> The enum representation in C is implementation defined, so this is really a "best guess". In particular, this may be incorrect when the C code of interest is compiled with certain flags.
355+
> For maximum portability, it is always preferred to set the size and alignment explicitly using a [primitive representation](#r-layout.repr.primitive.enum) on the Rust side, and a fixed underlying type on the C side.
352356
353357
> [!WARNING]
354358
> There are crucial differences between an `enum` in the C language and Rust's [field-less enums] with this representation. An `enum` in C is mostly a `typedef` plus some named constants; in other words, an object of an `enum` type can hold any integer value. For example, this is often used for bitflags in `C`. In contrast, Rust’s [field-less enums] can only legally hold the discriminant values, everything else is [undefined behavior]. Therefore, using a field-less enum in FFI to model a C `enum` is often wrong.
@@ -436,10 +440,11 @@ two primitive representations together is an error.
436440
r[layout.repr.primitive.enum]
437441
#### Primitive Representation of Field-less Enums
438442

439-
For [field-less enums], primitive representations set the size and alignment to
440-
be the same as the primitive type of the same name. For example, a field-less
441-
enum with a `u8` representation can only have discriminants between 0 and 255
442-
inclusive.
443+
For [field-less enums], primitive representations set the type of the discriminants
444+
to the primitive type of the same name. Furthermore, the enum's size and alignment are
445+
guaranteed to match that type. For example, a field-less
446+
enum with a `u8` representation has discriminants of type `u8` and hence
447+
can only have discriminants between 0 and 255 inclusive.
443448

444449
r[layout.repr.primitive.adt]
445450
#### Primitive Representation of Enums With Fields

0 commit comments

Comments
 (0)