---
title: "Packed Struct em Zig — O que é e Como Usar"
url: "https://ziglang.com.br/glossario/packed-struct-em-zig-o-que-%C3%A9-e-como-usar/"
markdown_url: "https://ziglang.com.br/glossario/packed-struct-em-zig-o-que-%C3%A9-e-como-usar.MD"
description: "Entenda packed structs em Zig: structs com layout de memória preciso, sem padding. Ideal para protocolos binários e hardware. Guia em pt-BR."
date: "2026-02-21"
author: "Zig Brasil"
---

# Packed Struct em Zig — O que é e Como Usar

Entenda packed structs em Zig: structs com layout de memória preciso, sem padding. Ideal para protocolos binários e hardware. Guia em pt-BR.


# Packed Struct em Zig — O que é e Como Usar

## Definição

Uma **packed struct** em Zig é uma struct declarada com a palavra-chave `packed` que possui um **layout de memória exato e previsível**, sem padding (bytes de preenchimento) entre os campos. Os campos são empacotados bit a bit, permitindo definir campos com tamanhos arbitrários em bits — como campos de 3 bits, 1 bit (booleano) ou 5 bits.

Packed structs são fundamentais para trabalhar com protocolos de rede, formatos de arquivo binário, registradores de hardware e qualquer situação onde o layout exato dos bits importa.

## Por que Packed Structs Importam

1. **Layout garantido**: Você sabe exatamente onde cada bit está na memória.
2. **Bitfields**: Campos podem ter tamanhos menores que 1 byte (ex: `u3`, `u1`).
3. **Interoperabilidade**: Mapeiam diretamente para estruturas de protocolos binários.
4. **Conversão segura**: Podem ser convertidas de/para inteiros com `@bitCast`.
5. **Hardware**: Permitem mapear registradores de dispositivos com precisão bit a bit.

## Exemplo Prático

### Bitfields para Protocolo

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

const CabecalhoTCP = packed struct {
    porta_origem: u16,
    porta_destino: u16,
    numero_sequencia: u32,
    numero_ack: u32,
    offset: u4,
    reservado: u3,
    flags: packed struct {
        ns: u1,
        cwr: u1,
        ece: u1,
        urg: u1,
        ack: u1,
        psh: u1,
        rst: u1,
        syn: u1,
        fin: u1,
    },
    janela: u16,
    checksum: u16,
    ponteiro_urgente: u16,
};

pub fn main() void {
    std.debug.print("Tamanho do cabeçalho: {} bytes\n", .{@sizeOf(CabecalhoTCP)});
}
```

### Conversão para Inteiro

```zig
const Flags = packed struct {
    leitura: bool,    // 1 bit
    escrita: bool,    // 1 bit
    execucao: bool,   // 1 bit
    _padding: u5 = 0, // 5 bits para completar 1 byte
};

pub fn main() void {
    const flags = Flags{
        .leitura = true,
        .escrita = true,
        .execucao = false,
    };

    // Converter para inteiro
    const valor: u8 = @bitCast(flags);
    std.debug.print("Flags como byte: 0b{b:0>8}\n", .{valor});
    // Saída: 0b00000011
}
```

### Lendo Dados Binários

```zig
fn lerCabecalho(dados: []const u8) *const CabecalhoTCP {
    return @ptrCast(@alignCast(dados.ptr));
}
```

### Packed vs Extern vs Normal

```zig
// Normal: compilador pode reordenar e adicionar padding
const Normal = struct {
    a: u8,
    b: u32,  // padding de 3 bytes antes de b
    c: u8,
};

// Packed: sem padding, campos empacotados bit a bit
const Packed = packed struct {
    a: u8,
    b: u32,
    c: u8,
};

// Extern: layout compatível com C ABI
const Extern = extern struct {
    a: u8,
    b: u32,
    c: u8,
};

// @sizeOf(Normal) >= 12 (com padding)
// @sizeOf(Packed) == 5 (sem padding)
// @sizeOf(Extern) == 12 (padding C)
```

## Armadilhas Comuns

- **Performance**: Acessar campos não alinhados em packed structs pode ser mais lento que structs normais. O processador pode precisar de instruções extras.
- **Ponteiros para campos**: Não é possível obter ponteiros para campos individuais de uma packed struct que não estejam alinhados a bytes.
- **Endianness**: Packed structs usam a endianness nativa. Para protocolos de rede (big-endian), use `std.mem.bigToNative` para converter.
- **Confundir com `extern struct`**: Para interop com C, use `extern struct`. Packed structs são para controle bit-a-bit.
- **Bool em packed struct**: `bool` ocupa 1 bit, não 1 byte como em structs normais.

## Casos de Uso

Packed structs são a ferramenta certa quando o layout exato dos bits na memória importa:

- **Registradores de hardware**: Microcontroladores expõem periféricos como registradores mapeados em memória com campos de tamanho específico em bits.
- **Protocolos de rede**: Formatos como IPv4, TCP e DNS têm campos com tamanhos arbitrários definidos pelos RFCs.
- **Formatos de arquivo**: Cabeçalhos de BMP, ELF, PNG e outros formatos binários definem layouts específicos.
- **Compressão de dados**: Representar flags e pequenos valores em poucos bits para economizar memória.

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

// Byte de flags típico em protocolos embarcados
const StatusReg = packed struct {
    pronto: u1,
    ocupado: u1,
    erro: u1,
    overflow: u1,
    _reservado: u4 = 0,
};

pub fn lerStatus(porta: u8) StatusReg {
    return @bitCast(porta);
}

pub fn main() void {
    const byte_recebido: u8 = 0b00000101; // pronto=1, erro=1
    const status = lerStatus(byte_recebido);
    std.debug.print("Pronto: {}, Erro: {}\n", .{ status.pronto, status.erro });
}
```

## Boas Práticas

- Sempre verifique o tamanho com `@sizeOf` e `@bitSizeOf` para confirmar que o layout está correto.
- Para protocolos de rede (big-endian), combine packed structs com `@byteSwap` ou `std.mem.bigToNative` após ler os dados.
- Use `_padding` com valor default zero para campos reservados, tornando o propósito explícito.
- Prefira `extern struct` quando a interoperabilidade com C for o objetivo; use `packed struct` apenas quando o controle bit a bit for necessário.

## Termos Relacionados

- [Struct](/glossario/struct/) — Structs regulares em Zig
- [Alignment](/glossario/alignment/) — Alinhamento de memória
- [Union](/glossario/union/) — Tipos union em Zig
- [Slice](/glossario/slice/) — Referências a sequências de memória

## Tutoriais Relacionados

- [Structs, Enums e Unions em Zig](/tutoriais/structs-enums-unions-zig/)
- [Zig e C — Interoperabilidade](/tutoriais/zig-c-interoperabilidade/)
- [Zig para Programadores C](/tutoriais/zig-para-programadores-c/)
