From b3d532f55bea88bf34aae8d3b6af4c5d1ceaf31e Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Wed, 8 Aug 2018 18:41:05 +0200 Subject: [PATCH] explain the empty type better, and explain to NOT use enums --- src/ffi.md | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/ffi.md b/src/ffi.md index a558b92..d766cf2 100644 --- a/src/ffi.md +++ b/src/ffi.md @@ -751,8 +751,17 @@ extern "C" { ``` By including a private field and no constructor, -we create an opaque type that we can’t instantiate outside of this module. -An empty array is both zero-size and compatible with `#[repr(C)]`. +we create an opaque type that we can't instantiate outside of this module. +(A struct with no field could be instantiated by anyone.) +We also want to use this type in FFI, so we have to add `#[repr(C)]`. +And to avoid warning around using `()` in FFI, we instead use an empty array, +which works just as well as an empty type but is FFI-compatible. + But because our `Foo` and `Bar` types are different, we’ll get type safety between the two of them, so we cannot accidentally pass a pointer to `Foo` to `bar()`. + +Notice that it is a really bad idea to use an empty enum as FFI type. +The compiler relies on empty enums being uninhabited, so handling values of type +`&Empty` is a huge footgun and can lead to buggy program behavior (by triggering +undefined behavior).