Add: windows mvp - transparent bugs not fixed

This commit is contained in:
DaZuo0122
2026-02-12 22:58:33 +08:00
commit 61825f647d
147 changed files with 28498 additions and 0 deletions

View File

@@ -0,0 +1,130 @@
---
id: mem-01
original_id: P.UNS.MEM.01
level: P
impact: HIGH
---
# Choose Appropriate Data Layout for Struct/Tuple/Enum
## Summary
Use `#[repr(...)]` attributes to control data layout when interfacing with C, doing memory mapping, or needing specific guarantees.
## Rationale
Rust's default layout is unspecified and may change between compiler versions. For FFI, persistence, or low-level memory operations, you need predictable layout.
## Repr Attributes
| Attribute | Use Case |
|-----------|----------|
| `#[repr(C)]` | C-compatible layout, stable field order |
| `#[repr(transparent)]` | Single-field struct with same layout as field |
| `#[repr(packed)]` | No padding (alignment = 1), careful with references! |
| `#[repr(align(N))]` | Minimum alignment of N bytes |
| `#[repr(u8)]`, `#[repr(i32)]`, etc. | Enum discriminant type |
## Bad Example
```rust
// DON'T: Assume Rust struct layout matches C
struct BadFFI {
a: u8,
b: u32,
c: u8,
}
// Rust may reorder fields or add different padding than C
// DON'T: Use packed without understanding the risks
#[repr(packed)]
struct Dangerous {
a: u8,
b: u32,
}
fn bad_ref(d: &Dangerous) -> &u32 {
&d.b // UB: Creates unaligned reference!
}
```
## Good Example
```rust
// DO: Use repr(C) for FFI
#[repr(C)]
struct GoodFFI {
a: u8,
b: u32,
c: u8,
}
// Guaranteed: a at 0, padding 1-3, b at 4, c at 8, padding 9-11
// DO: Use repr(transparent) for newtypes
#[repr(transparent)]
struct Wrapper(u32);
// Guaranteed same layout as u32, can be transmuted
// DO: Use repr(packed) carefully, access via copy
#[repr(C, packed)]
struct PackedData {
header: u8,
value: u32,
}
impl PackedData {
fn value(&self) -> u32 {
// Copy out the value to avoid unaligned reference
let ptr = std::ptr::addr_of!(self.value);
// SAFETY: Reading unaligned is OK with read_unaligned
unsafe { ptr.read_unaligned() }
}
}
// DO: Use align for SIMD or cache line alignment
#[repr(C, align(64))]
struct CacheAligned {
data: [u8; 64],
}
// DO: Specify enum discriminant for FFI
#[repr(u8)]
enum Status {
Ok = 0,
Error = 1,
Unknown = 255,
}
```
## Layout Guarantees
```rust
use std::mem::{size_of, align_of};
#[repr(C)]
struct Example {
a: u8, // offset 0, size 1
// padding: 3 bytes
b: u32, // offset 4, size 4
c: u8, // offset 8, size 1
// padding: 3 bytes
}
assert_eq!(size_of::<Example>(), 12);
assert_eq!(align_of::<Example>(), 4);
// repr(Rust) might reorder to: b, a, c -> size 8
```
## Checklist
- [ ] Is this type used in FFI? → Use `#[repr(C)]`
- [ ] Is this a newtype wrapper? → Consider `#[repr(transparent)]`
- [ ] Do I need specific alignment? → Use `#[repr(align(N))]`
- [ ] Am I using packed? → Never create references to packed fields
## Related Rules
- `ffi-13`: Ensure consistent data layout for custom types
- `ffi-14`: Types in FFI should have stable layout
- `ptr-04`: Alignment considerations