struct layout
- Rust kursu
- Uzman
- Ders 7/46
- 4 dk
Struct alanlarının bellek düzenini ve sırasını öğrenirsin.
struct layout
Varsayılan (repr(Rust)) düzende derleyici alanların sırasını değiştirebilir; amacı boşluğu (padding) en aza indirmektir. Genellikle alanları hizalamaya göre büyükten küçüğe dizer. Bu düzen belgelenmiş bir garanti değildir; aynı tanım farklı derleyici sürümlerinde farklı yerleşebilir:
struct Rust { a: u8, b: u64, c: u16 } // yeniden sıralanır: 16 bayt
#[repr(C)]
struct C { a: u8, b: u64, c: u16 } // yazıldığı sırayla: 24 baytrepr(C)'de: a (1) + 7 boşluk + b (8) + c (2) + 6 boşluk = 24. Rust düzeninde: b (8) + c (2) + a (1) + 5 boşluk = 16.
Düzeni gözlemlemek
offset_of!, derleyicinin seçtiği yerleşimi gösterir; -Zprint-type-sizes (nightly) tüm türlerin ayrıntılı düzenini yazdırır:
use std::mem::offset_of;
println!("{}", offset_of!(C, b)); // 8
println!("{}", offset_of!(C, c)); // 16
println!("{}", offset_of!(Rust, b)); // genellikle 0 (garanti değil)Düzene güvenen kod (FFI, ikili dosya biçimleri, transmute) mutlaka repr(C) ya da başka bir açık repr kullanmalıdır.
Uygulama İki düzen
Aynı alanlara (a: u8, b: u64, c: u16) sahip düz struct Rust ve #[repr(C)] struct C tanımla. İkisinin size_of değerini boşlukla yazdır.
Başlangıç kodu
fn main() {
// buraya yaz
}Örnek çözüm
#![allow(dead_code)]
use std::mem::size_of;
struct Rust {
a: u8,
b: u64,
c: u16,
}
#[repr(C)]
struct C {
a: u8,
b: u64,
c: u16,
}
fn main() {
println!("{} {}", size_of::<Rust>(), size_of::<C>());
}Beklenen çıktı
16 24
Soru ve cevaplar
Dersin sorularını cevaplarıyla birlikte inceleyebilirsin. Kendini denemek istersen dersi interaktif olarak çöz.
1 Neden struct boyutu en büyük hizalamanın katına yuvarlanır?
- Hız için rastgele
- Yuvarlanmaz
- İşletim sistemi ister
- Dizideki her elemanın da doğru hizalanması için Doğru cevap
Açıklama: [T; N] içinde elemanlar arka arkaya durur; size_of::<T>() hizalamanın katı olmasaydı ikinci eleman yanlış hizalanırdı.
2 Alan konumu
use std::mem::offset_of;
println!("{}", ____!(C, b)); // 8
use std::mem::offset_of;
println!("{}", offset_of!(C, b)); // 8
Açıklama: offset_of! bir alanın struct başından bayt uzaklığını verir.
3 Tanım ve boyut
| Kavram | Anlamı |
|---|---|
Rust { a: u8, b: u64, c: u16 } |
16 |
#[repr(C)] C { a: u8, b: u64, c: u16 } |
24 |
offset_of!(C, b) |
8 (konum) |
(u8, u64) |
16 (demet) |