Saltar al contenido

Layout de Memoria

En esta página

Por defecto, el compilador de Zolo puede reordenar los campos de un struct (@repr(zolo)) para optimización interna. Cuando el orden y el alineamiento de los campos son contratos — FFI con C/Rust, uniform buffers de GPU, protocolos binarios — declaras el layout explícitamente con atributos:

@repr(C), @repr(packed), @repr(transparent), @align(N) y @size(N).

13-repr-align-size.zolo
Playground
// Feature: `@repr` / `@align` / `@size` — struct layout control

// Syntax:

//   @repr(C | packed | transparent | zolo)   on the struct

//   @align(N)   on a field (N must be a power of two)

//   @size(N)    on a field (forces minimum byte size)

// When to use: FFI with C/Rust plugins, GPU uniform buffers, binary

//   protocols, layout-sensitive newtypes. Default `@repr(zolo)` lets

//   the compiler reorder fields, which is unsuitable for binary stability.

//

// See `specs/repr-align-size.md` for the full specification.


// 1. @repr(C) — fields kept in declaration order, C-compatible layout.

@repr(C)
struct PacketHeader {
    version: int,
    flags: int,
    length: int,
    seq: int,
}

let hdr = PacketHeader { version: 1, flags: 0, length: 256, seq: 42 }
print("hdr.seq = {hdr.seq}")

// 2. @repr(packed) — no padding between fields.

//    Useful for wire protocols where every byte matters.

@repr(packed)
struct WireFrame {
    magic: int,
    payload: int,
}

let w = WireFrame { magic: 0xCAFE, payload: 100 }
print("w.magic = {w.magic}")

// 3. @repr(transparent) — single-field newtype-like with identical

//    binary layout to its inner field.

@repr(transparent)
struct Handle {
    raw: int,
}

let h = Handle { raw: 42 }
print("h.raw = {h.raw}")

// 4. @align(N) on a field — force alignment under @repr(C).

//    Useful for GPU uniform buffers where vec3 must be 16-byte aligned.

@repr(C)
struct CameraUniform {
    @align(16) view_proj: float,
    @align(16) view_pos:  float,
    @align(16) time:      float,
}

let cam = CameraUniform { view_proj: 1.0, view_pos: 0.0, time: 0.5 }
print("cam.time = {cam.time}")

// 5. @size(N) on a field — pad to a minimum byte size.

@repr(C)
struct PaddedHeader {
    @size(64) header: int,
    payload: int,
}

let p = PaddedHeader { header: 1, payload: 2 }
print("p.payload = {p.payload}")

// 6. Errors caught at lint/check time (uncomment to see):

//

//   @repr(unknown_policy)

//   struct X { x: int }

//     warning[unknown-repr]: unknown @repr policy `unknown_policy`

//

//   @repr(transparent)

//   struct Two { a: int, b: int }

//     error[transparent-multi-field]: @repr(transparent) requires exactly one field

//

//   @repr(C)

//   struct Bad {

//       @align(3) x: int     // not a power of two

//       @align(8192) y: int  // exceeds 4096

//   }

//     error[align-not-power-of-two]

//     error[align-too-large]

//

//   struct DefaultRepr {

//       @align(8) x: int   // @align without @repr — meaningless

//   }

//     error[layout-in-default-repr]: `@align` requires an explicit

//                                    `@repr(C|packed|transparent)` on the struct

Referencia rápida:

  • @repr(C) — campos en orden de declaración, compatible con C.
  • @repr(packed) — sin padding entre campos (protocolo de red, archivo binario).
  • @repr(transparent) — requiere exactamente un campo; layout idéntico al tipo interno.
  • @align(N) — en un campo, fuerza el alineamiento a N bytes (potencia de dos, máx. 4096).
  • @size(N) — en un campo, garantiza un tamaño mínimo de N bytes.

@align y @size requieren que el struct tenga un @repr explícito (no zolo). El compilador emite un error en tiempo de verificación si la combinación es inválida.

Consulta también

Buscar en Zolo

9 resultados

enespt-br