---
title: "Alignment (Alinhamento) em Zig — O que é e Como Usar"
url: "https://ziglang.com.br/glossario/alignment-alinhamento-em-zig-o-que-%C3%A9-e-como-usar/"
markdown_url: "https://ziglang.com.br/glossario/alignment-alinhamento-em-zig-o-que-%C3%A9-e-como-usar.MD"
description: "Entenda alinhamento de memória em Zig: como dados são posicionados na RAM para acesso eficiente do processador. Guia completo em pt-BR."
date: "2026-02-21"
author: "Zig Brasil"
---

# Alignment (Alinhamento) em Zig — O que é e Como Usar

Entenda alinhamento de memória em Zig: como dados são posicionados na RAM para acesso eficiente do processador. Guia completo em pt-BR.


# Alignment (Alinhamento) em Zig — O que é e Como Usar

## Definição

**Alignment** (alinhamento) em Zig refere-se à restrição de que certos tipos de dados devem estar posicionados em endereços de memória que são **múltiplos de um valor específico**. Por exemplo, um `u32` tipicamente requer alinhamento de 4 bytes — seu endereço deve ser divisível por 4.

O alinhamento existe porque processadores acessam memória de forma mais eficiente (e às vezes apenas) quando os dados estão alinhados corretamente. Zig expõe o controle de alinhamento diretamente no sistema de tipos.

## Por que Alignment Importa

1. **Performance**: Acesso alinhado é mais rápido; acesso não-alinhado pode custar 2x ou mais.
2. **Correção**: Em algumas arquiteturas (ARM, RISC-V), acesso não-alinhado causa falha de hardware.
3. **SIMD/Vetores**: Operações vetoriais exigem alinhamento específico (16, 32 ou 64 bytes).
4. **Interop com C**: O ABI C define alinhamentos que Zig precisa respeitar em `extern struct`.

## Exemplo Prático

### Consultando Alinhamento

```zig
const std = @import("std");

pub fn main() void {
    std.debug.print("u8:  align = {}\n", .{@alignOf(u8)});   // 1
    std.debug.print("u16: align = {}\n", .{@alignOf(u16)});  // 2
    std.debug.print("u32: align = {}\n", .{@alignOf(u32)});  // 4
    std.debug.print("u64: align = {}\n", .{@alignOf(u64)});  // 8
    std.debug.print("f64: align = {}\n", .{@alignOf(f64)});  // 8
}
```

### Ponteiros com Alinhamento Customizado

```zig
fn processarSIMD(dados: [*]align(16) const f32) void {
    // Dados garantidamente alinhados a 16 bytes
    // Operações SIMD seguras aqui
    _ = dados;
}

pub fn main() void {
    // Array com alinhamento customizado
    var buffer align(16) = [_]f32{ 1.0, 2.0, 3.0, 4.0 };
    processarSIMD(&buffer);
}
```

### Alinhamento em Structs

```zig
const std = @import("std");

const SemPadding = extern struct {
    a: u32, // offset 0, align 4
    b: u32, // offset 4, align 4
    c: u32, // offset 8, align 4
};

const ComPadding = extern struct {
    a: u8,  // offset 0, align 1
    // 3 bytes de padding aqui!
    b: u32, // offset 4, align 4
    c: u8,  // offset 8, align 1
    // 3 bytes de padding aqui!
};

pub fn main() void {
    std.debug.print("SemPadding: {} bytes\n", .{@sizeOf(SemPadding)});  // 12
    std.debug.print("ComPadding: {} bytes\n", .{@sizeOf(ComPadding)});  // 12 (com padding!)

    // Reordenando para economizar:
    const Otimizado = extern struct {
        b: u32, // offset 0
        a: u8,  // offset 4
        c: u8,  // offset 5
        // 2 bytes de padding
    };
    std.debug.print("Otimizado: {} bytes\n", .{@sizeOf(Otimizado)});  // 8
}
```

### @alignCast

```zig
fn processar(ptr: *align(1) u32) void {
    // ptr pode estar em qualquer endereço
    // Para operações que exigem alinhamento natural:
    const alinhado: *u32 = @alignCast(ptr);
    _ = alinhado;
}
```

### Alocação com Alinhamento Específico

```zig
const std = @import("std");

pub fn main() !void {
    const allocator = std.heap.page_allocator;

    // Alocar com alinhamento customizado
    const dados = try allocator.alignedAlloc(f32, 32, 1024);
    defer allocator.free(dados);

    // dados está alinhado a 32 bytes — ideal para AVX
    std.debug.print("Endereço: {*}\n", .{dados.ptr});
}
```

## Alinhamentos Comuns

| Tipo | Alinhamento típico (x86_64) |
|------|----------------------------|
| `u8`, `i8` | 1 byte |
| `u16`, `i16` | 2 bytes |
| `u32`, `i32`, `f32` | 4 bytes |
| `u64`, `i64`, `f64` | 8 bytes |
| `u128`, `i128` | 16 bytes |
| SIMD `@Vector(4, f32)` | 16 bytes |
| Cache line | 64 bytes |

## Por que a Ordem dos Campos Importa

Em structs `extern`, o compilador não reordena os campos automaticamente — ele insere padding para satisfazer os requisitos de alinhamento de cada campo. A ordem que você declara os campos determina quanto espaço é desperdiçado:

```zig
// Má ordem: mais padding
const Ruim = extern struct { a: u8, b: u32, c: u8, d: u32 };

// Boa ordem: campos do maior para o menor alinhamento
const Bom = extern struct { b: u32, d: u32, a: u8, c: u8 };
```

Use `@sizeOf` para verificar o resultado. A regra prática é: declare campos do maior para o menor alinhamento.

## Boas Práticas

- **Reordene campos em structs grandes**: Em structs que serão instanciadas em grandes quantidades (ex: entidades de um game), economizar bytes por instância multiplica pelo número de objetos.
- **Use `@sizeOf` e `@offsetOf` para inspecionar**: Verifique explicitamente o tamanho e o offset de campos em structs críticas. `@offsetOf(MinhaStruct, "campo")` retorna o offset em bytes.
- **Alinhamento explícito em buffers SIMD**: Ao alocar buffers para operações SIMD, use `alignedAlloc` com o alinhamento do registrador (16 para SSE, 32 para AVX).
- **`packed struct` para protocolo de rede**: Quando você precisa de controle total sobre o layout bit a bit (cabeçalhos de protocolos, formatos de arquivo), use `packed struct` — ele remove o padding mas exige acessos via `@bitCast`.

## Armadilhas Comuns

- **Ignorar alinhamento em interop C**: Structs `extern` devem respeitar o alinhamento do ABI C. Use `extern struct` em vez de `struct`.
- **`@alignCast` inseguro**: Se o ponteiro não estiver realmente alinhado, `@alignCast` causa comportamento indefinido em Release.
- **Padding desperdiça memória**: Em arrays de structs com padding, o desperdício se multiplica. Reordene campos para minimizar padding.
- **Assumir alinhamento**: Diferentes arquiteturas têm diferentes requisitos. Não assuma que funciona em x86 significa que funciona em ARM.

## Termos Relacionados

- [Packed Struct](/glossario/packed-struct/) — Structs sem padding
- [Pointer Types](/glossario/pointer-types/) — Tipos de ponteiro com alinhamento
- [Vector/SIMD](/glossario/vector-simd/) — Tipos vetoriais que exigem alinhamento
- [Struct](/glossario/struct/) — Structs e layout de memória

## Tutoriais Relacionados

- [Zig para Programadores C](/tutoriais/zig-para-programadores-c/)
- [Zig SIMD Guide](/tutoriais/zig-simd-guide/)
- [Zig e C — Interoperabilidade](/tutoriais/zig-c-interoperabilidade/)
