Attribute Macro ark_api_macros::ffi_union
source · #[ffi_union]
Expand description
Performs modification necessary to make a union ffi-safe.
Ultimately this checks for invariants and implements bytemuck::NoUninit
and bytemuck::AnyBitPattern
. It is
technically possible to make the bytemuck::NoUninit
implementation invalid with sound code,
but only through using unsafe code that writes uninit memory into the union. Therefore you have
to promise not to do this… which ultimately shouldn’t be an issue as this isn’t really something
that should be a want to do.
This macro wraps each field in a union into an ark_api_ffi::TransparentPad<T, N>
such that the total size of the new type is equal to the size specified in the
ffi_union
macro. The size is specified in bytes.
This macro automatically derives bytemuck::NoUninit
and bytemuck::AnyBitPattern
for the union it is applied to, which is necessary so that those derives use the
modified version of the union definition.
§Expected form
#[ark_api_macros::ffi_union(size = <size>, <pod_accessors | checked_accessors>)]
§Example
#[ark_api_macros::ffi_union(size = 8, pod_accessors)]
union AutoPadExample {
field1: u64,
field2: u32,
}
Usually, this would result in a union of size 8 but with padding for bytes 4-8
when the used field is field2
. This macro will expand this to (basically):
#[derive(NoUninit, AnyBitPattern)]
union AutoPadExample {
field1: TransparentPad<u64, 0>,
field2: TransparentPad<u32, 4>,
}
which adds “explicit”/“manual” padding bytes to the end of field2
– making the
compiler not treat them as real padding.
This macro will also derive accessor methods on the union for each field in the form
as_{field_name}
(and try_as_{field_name}
, if using checked_accessors
) that return references
to the field as the field’s original type rather than as the wrapped TransparentPad
.
These accessors will either use bytemuck
’s raw or checked casting functions based on
the second argument to the proc macro, which can be either pod_accessors
or checked_accessors
.
All fields must implement Pod
for pod_accessors
, while all fields must implement
CheckedBitPattern
for checked_accessors
.