Имеет ли приведение указателей в Rust то же поведение, что и reinterpret_cast в C ++? - PullRequest
0 голосов
/ 15 июня 2019

У меня есть эта структура, определенная в моем коде:

#[repr(align(4))]
struct MetaDataDefn {
  cncVersion: i32,
  toDriverBufferLength: i32,
  toClientsBufferLength: i32,
  counterMetadataBufferLength: i32,
  counterValuesBuferLength: i32,
  clientLivenessTimeout: i64,
  startTimestamp: i64,
  pid: i64
}

У меня есть функция, которая берет необработанный указатель на кусок памяти, где первые байты соответствуют структуре с той же компоновкой.Я думал, что если я приведу указатель u8 к указателю структуры, я получу тот же результат, как если бы я сделал reinterpret_cast в C ++.Тем не менее, я думаю, что это не так, и я немного озадачен тем, что здесь происходит.Это тело функции (указатель, который получает функция - cncFilePtr):

let metadata = unsafe { cncFilePtr as *mut MetaDataDefn };

// This works
let cncVersion = unsafe { (*(cncFilePtr as *mut i32)) };
println!("CNC Version: {}", cncVersion);

//This prints a different number than the previous code
println!("CNC version (other way): {}", unsafe { (*metadata).cncVersion });

Как видите, приведение первых 4 байтов к i32 и последующая печать результата дает результат, отличный отприведение всего этого к MetaDataDefn и доступ к первому члену типа i32 (насколько я понимаю, оба подхода должны давать один и тот же результат)

Мой вопрос: почему это не тот же результат?Разве приведение указателей в Rust не совпадает с приведением reinterpret_cast в C ++ (я из C ++ фона)?

1 Ответ

2 голосов
/ 15 июня 2019

Обычно Rust не дает никаких гарантий относительно того, как структура представлена ​​в памяти. Он может изменить порядок полей, чтобы сделать их более плотными, и теоретически может даже оптимизировать порядок полей в зависимости от того, как ваше приложение на самом деле обращается к ним.

Вы можете исправить порядок, ведя себя как C, добавив атрибут #[repr(C)]:

#[repr(C)]
#[repr(align(4))]
struct MetaDataDefn { ... }

При этом оба указателя дадут одинаковый результат, поскольку это гарантирует, что cncVersion появится первым.

...