Атрибут #[repr(transparent)]
Атрибут #[repr(transparent)] применяется к структурам и перечислениям с одним непустым полем. Он гарантирует, что тип имеет такое же представление в памяти и такой же ABI, как и это единственное поле. Это особенно важно при работе с unsafe-кодом и FFI, когда нужно передать обёртку в C-функцию без накладных расходов. Атрибут не принимает параметров.
Синтаксис
#[repr(transparent)]
struct Name(FieldType);
#[repr(transparent)]
enum Name
{
Variant(FieldType),
}
Пример
Давайте создадим прозрачную обёртку над u32 и проверим, что размер и выравнивание совпадают:
use std::mem::{size_of, align_of};
#[repr(transparent)]
struct Wrapper(u32);
fn main()
{
println!("{}", size_of::<Wrapper>());
println!("{}", size_of::<u32>());
println!("{}", align_of::<Wrapper>());
println!("{}", align_of::<u32>());
}
Результат выполнения кода:
4
4
4
4
Пример
Давайте используем прозрачную структуру для передачи в C-функцию через extern "C":
#[repr(transparent)]
struct Id(u64);
extern "C"
{
fn process_id(id: u64) -> u64;
}
unsafe fn call_process(id: Id) -> u64
{
process_id(id.0)
}
fn main()
{
let id = Id(12345);
let res = unsafe { call_process(id) };
println!("{}", res);
}
Результат выполнения кода:
12345
Пример
Давайте создадим прозрачное перечисление с одним вариантом и проверим его размер:
use std::mem::size_of;
#[repr(transparent)]
enum Flag
{
Value(bool),
}
fn main()
{
println!("{}", size_of::<Flag>());
println!("{}", size_of::<bool>());
}
Результат выполнения кода:
1
1
Смотрите также
-
атрибут
repr-c,
который задаёт C-совместимое представление -
атрибут
repr-packed,
который убирает выравнивание полей -
ключевое слово
unsafe,
которое открывает доступ к небезопасным операциям -
ключевое слово
extern "C",
которое задаёт C-совместимый ABI для функций