You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: src/type-layout.md
+11-6Lines changed: 11 additions & 6 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -344,11 +344,15 @@ assert_eq!(std::mem::align_of::<SizeRoundedUp>(), 4); // From a
344
344
r[layout.repr.c.enum]
345
345
#### `#[repr(C)]` Field-less Enums
346
346
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).
349
352
350
353
> [!NOTE]
351
354
> 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.
352
356
353
357
> [!WARNING]
354
358
> 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.
436
440
r[layout.repr.primitive.enum]
437
441
#### Primitive Representation of Field-less Enums
438
442
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.
443
448
444
449
r[layout.repr.primitive.adt]
445
450
#### Primitive Representation of Enums With Fields
0 commit comments