Description
We have a lot of FFI declarations in the code, and the style of these declarations is not always consistent:
- Most are declared
unsafe
, but not all. - Some places
*const
/*mut
, others use&
/&mut
. Using references can be correct since they are layout-compatible with pointers, but it's not always clear from the spec what the restrictions are on how a pointer gets used, so using references may lead to UB. - Some places use wrappers like
Option
/NonNull
. These can be perfectly correct in cases where the layout is well defined and FFI-compatible, but the inconsistency can still make it harder to verify correctness.
Another layer of confusion comes from the IN
/OUT
/OPTIONAL
/CONST
modifiers in the spec. Sometimes these are used in weird ways (e.g. OPTIONAL
is defined as allowing NULL
to be passed in, but sometimes it's applied to non-pointer parameters). Sometimes they seem more like guides than rules (IN
and OUT
in particular seem more like semantic hints). So in general the safest way to define an FFI pointer is probably to use *mut
... but if that pointer is initialized from a &
reference in a safe wrapper we provide then that might just be moving the location of possible UB down a level.
See also some good relevant discussion here: r-efi/r-efi#46