---
title: "@sizeOf em Zig — Referência e Exemplos"
url: "https://ziglang.com.br/builtins/@sizeof-em-zig-refer%C3%AAncia-e-exemplos/"
markdown_url: "https://ziglang.com.br/builtins/@sizeof-em-zig-refer%C3%AAncia-e-exemplos.MD"
description: "Referência completa do @sizeOf em Zig. Aprenda a consultar o tamanho em bytes de tipos com exemplos práticos em português."
date: "2026-02-21"
author: "Zig Brasil"
---

# @sizeOf em Zig — Referência e Exemplos

Referência completa do @sizeOf em Zig. Aprenda a consultar o tamanho em bytes de tipos com exemplos práticos em português.


# @sizeOf em Zig

O `@sizeOf` retorna o tamanho de armazenamento de um tipo em bytes, incluindo qualquer padding de alinhamento. É o equivalente do `sizeof` do C, mas disponível como builtin em tempo de compilação. Fundamental para alocação de memória, serialização e interoperabilidade com código C.

## Sintaxe

```zig
@sizeOf(comptime T: type) comptime_int
```

## O que faz

O `@sizeOf` consulta o tamanho que um valor do tipo especificado ocupa na memória, em bytes. O valor retornado inclui qualquer padding inserido pelo compilador para manter o alinhamento correto. Este é o número de bytes que um `std.mem.Allocator` alocaria para uma instância desse tipo.

## Parâmetros

- **T** (`type`, comptime): O tipo cujo tamanho será consultado. Pode ser qualquer tipo válido exceto `comptime_int`, `comptime_float` e outros tipos que existem apenas em comptime.

## Valor de retorno

Retorna um `comptime_int` representando o tamanho em bytes do tipo.

## Exemplos práticos

### Exemplo 1: Tamanho de tipos primitivos

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

test "tamanho de tipos primitivos" {
    try std.testing.expect(@sizeOf(u8) == 1);
    try std.testing.expect(@sizeOf(u16) == 2);
    try std.testing.expect(@sizeOf(u32) == 4);
    try std.testing.expect(@sizeOf(u64) == 8);
    try std.testing.expect(@sizeOf(i32) == 4);
    try std.testing.expect(@sizeOf(f32) == 4);
    try std.testing.expect(@sizeOf(f64) == 8);
    try std.testing.expect(@sizeOf(bool) == 1);

    // Ponteiros em sistemas de 64 bits
    try std.testing.expect(@sizeOf(*u8) == 8);
    try std.testing.expect(@sizeOf(usize) == 8);
}
```

### Exemplo 2: Entendendo padding em structs

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

const SemPadding = struct {
    a: u32,
    b: u32,
};

const ComPadding = struct {
    a: u8,    // 1 byte + 7 de padding
    b: u64,   // 8 bytes
    c: u8,    // 1 byte + 7 de padding
};

const Otimizada = struct {
    b: u64,   // 8 bytes
    a: u8,    // 1 byte
    c: u8,    // 1 byte + 6 de padding
};

test "padding em structs" {
    try std.testing.expect(@sizeOf(SemPadding) == 8);   // 4 + 4
    std.debug.print("ComPadding: {} bytes\n", .{@sizeOf(ComPadding)});
    std.debug.print("Otimizada: {} bytes\n", .{@sizeOf(Otimizada)});

    // Reordenar campos pode reduzir o tamanho total
    // ComPadding provavelmente é 24 bytes (com padding)
    // Otimizada provavelmente é 16 bytes (menos padding)
}
```

### Exemplo 3: Buffer de serialização

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

const Cabecalho = packed struct {
    versao: u8,
    tipo: u8,
    tamanho: u16,
    id: u32,
};

fn serializar(cabecalho: Cabecalho) [@sizeOf(Cabecalho)]u8 {
    return @bitCast(cabecalho);
}

fn deserializar(bytes: [@sizeOf(Cabecalho)]u8) Cabecalho {
    return @bitCast(bytes);
}

test "serialização com tamanho conhecido" {
    // packed struct garante layout previsível
    try std.testing.expect(@sizeOf(Cabecalho) == 8);

    const cab = Cabecalho{
        .versao = 1,
        .tipo = 3,
        .tamanho = 256,
        .id = 42,
    };

    const bytes = serializar(cab);
    const recuperado = deserializar(bytes);

    try std.testing.expect(recuperado.versao == 1);
    try std.testing.expect(recuperado.id == 42);
}
```

## Casos de uso comuns

1. **Alocação de memória**: Calcular quantos bytes alocar para arrays ou buffers de tipos específicos.
2. **Serialização binária**: Determinar o tamanho de estruturas para leitura/escrita em arquivos ou rede.
3. **Interoperabilidade com C**: Garantir que structs Zig tenham o mesmo tamanho que as equivalentes em C.
4. **Otimização de structs**: Comparar tamanhos com diferentes ordenações de campos para minimizar padding.
5. **Pools de memória**: Dimensionar pools e caches baseados no tamanho dos objetos armazenados.

## Diferenças entre @sizeOf e @bitSizeOf

- `@sizeOf` retorna o tamanho em **bytes**, incluindo padding de alinhamento.
- `@bitSizeOf` retorna o tamanho em **bits**, sem incluir padding extra.
- Para um `u24`, `@sizeOf` retorna 4 (arredondado para bytes com alinhamento), enquanto `@bitSizeOf` retorna 24.

## Comportamento com tipos especiais

Alguns tipos merecem atenção especial ao usar `@sizeOf`:

- **Tipos comptime-only** (`comptime_int`, `comptime_float`, `type`): `@sizeOf` não é aplicável e causa erro de compilação.
- **`void`**: `@sizeOf(void) == 0`. Void é um tipo de tamanho zero — útil para containers genéricos onde o tipo pode ser void.
- **`noreturn`**: Erro de compilação, pois não existe instância de `noreturn`.
- **Slices** (`[]T`): `@sizeOf([]T) == 2 * @sizeOf(usize)` — um slice é fat pointer (ponteiro + comprimento).
- **Tipos opcionais** (`?T`): Pode ser maior que `T` por adicionar um byte de discriminante, ou igual se T já tiver um valor inválido reservado (null pointer optimization).

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

test "tamanhos especiais" {
    try std.testing.expect(@sizeOf(void) == 0);
    try std.testing.expect(@sizeOf([]u8) == 2 * @sizeOf(usize)); // fat pointer
    try std.testing.expect(@sizeOf(?*u8) == @sizeOf(*u8)); // null pointer optimization
    try std.testing.expect(@sizeOf(?u32) == 8); // u32 + padding + discriminante
}
```

## Otimização de layout de struct

Reordenar campos de uma struct pode reduzir significativamente seu tamanho em memória, eliminando padding desnecessário. A regra geral é ordenar campos do maior para o menor alinhamento:

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

// Layout ruim: 24 bytes por causa do padding
const Ruim = struct {
    flag: bool,   // 1 byte + 7 de padding
    valor: u64,   // 8 bytes
    id: u32,      // 4 bytes + 4 de padding
};

// Layout otimizado: 16 bytes
const Bom = struct {
    valor: u64,   // 8 bytes
    id: u32,      // 4 bytes
    flag: bool,   // 1 byte + 3 de padding (para alinhar a próxima instância)
};

test "otimização de layout" {
    std.debug.print("Ruim: {} bytes\n", .{@sizeOf(Ruim)}); // 24
    std.debug.print("Bom: {} bytes\n", .{@sizeOf(Bom)});   // 16
}
```

## Comparação com `sizeof` do C

O `@sizeOf` do Zig é semanticamente idêntico ao `sizeof` do C para tipos compatíveis. Ambos incluem padding de alinhamento. A diferença é que em Zig é um builtin da linguagem, sempre avaliado em comptime, sem necessidade de cabeçalhos:

```c
// C
#include <stdio.h>
printf("%zu\n", sizeof(int));    // 4
printf("%zu\n", sizeof(float));  // 4
```

```zig
// Zig
std.debug.print("{}\n", .{@sizeOf(i32)}); // 4
std.debug.print("{}\n", .{@sizeOf(f32)}); // 4
```

Para `packed struct` em Zig, `@sizeOf` retorna o tamanho exato sem padding extra — equivalente a `__attribute__((packed))` no GCC.

## Perguntas Frequentes

**P: Por que `@sizeOf(bool) == 1` se bool só precisa de 1 bit?**

R: Em Zig (como em C), o menor endereçável é o byte. Não é possível ter uma variável que ocupa apenas 1 bit de memória endereçável individualmente. Para compactar múltiplos bools, use `packed struct` ou campos de bits.

**P: `@sizeOf` e `@bitSizeOf` sempre retornam valores consistentes?**

R: Para tipos primitivos, `@sizeOf(T) * 8 == @bitSizeOf(T)`. Para `u24`, porém, `@sizeOf` pode retornar 4 (arredondado para alinhamento) enquanto `@bitSizeOf` retorna 24. Em `packed struct`, os campos são compactados e `@bitSizeOf` reflete o tamanho real sem padding.

**P: Como usar `@sizeOf` para calcular o número de elementos que cabem em um buffer?**

R: Divida o tamanho do buffer pelo tamanho do elemento:

```zig
const BUFFER_SIZE = 4096;
var buffer: [BUFFER_SIZE]u8 = undefined;
const n_elementos = BUFFER_SIZE / @sizeOf(MinhaStruct);
```

## Builtins relacionados

- [@bitSizeOf](/builtins/bit-size-of/) — Retorna o tamanho em bits
- [@alignOf](/builtins/align-of/) — Retorna o alinhamento de um tipo
- [@typeInfo](/builtins/type-info/) — Informações detalhadas sobre o tipo
- [@memcpy](/builtins/memcpy/) — Copia bloco de memória

## Tutoriais relacionados

- [Layout de memória em Zig](/tutoriais/memoria/)
- [Structs e layout](/tutoriais/structs/)
- [Interoperabilidade com C](/tutoriais/interop-c/)
