Pular para o conteúdo

09 · Estruturas de Dados

Layout de Memória

`@repr`, `@align` e `@size` para controle de layout em FFI e GPU.

Nesta página

Por padrão, o compilador Zolo pode reordenar os campos de um struct (@repr(zolo)) para otimização interna. Quando a ordem e o alinhamento são contratos — FFI com C/Rust, uniform buffers de GPU, protocolos binários — você declara o layout explicitamente com atributos:

@repr(C), @repr(packed), @repr(transparent), @align(N) e @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

Referência rápida:

  • @repr(C) — campos na ordem de declaração, compatível com C.
  • @repr(packed) — sem padding entre campos (protocolo de rede, arquivo binário).
  • @repr(transparent) — exige exatamente um campo; layout idêntico ao tipo interno.
  • @align(N) — em um campo, força alinhamento a N bytes (potência de dois, máx. 4096).
  • @size(N) — em um campo, garante tamanho mínimo de N bytes.

@align e @size exigem que o struct tenha um @repr explícito (não zolo). O compilador emite erro em tempo de verificação se a combinação for inválida.

Índice global

Encontre seu caminho pela Zolo

Experimente uma ideia

Comece por aqui

9 resultados

9 resultados

enespt-br