@sizeOf em Zig — Referência e Exemplos

@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

@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

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

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

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.

Builtins relacionados

  • @bitSizeOf — Retorna o tamanho em bits
  • @alignOf — Retorna o alinhamento de um tipo
  • @typeInfo — Informações detalhadas sobre o tipo
  • @memcpy — Copia bloco de memória

Tutoriais relacionados

Continue aprendendo Zig

Explore mais tutoriais e artigos em português para dominar a linguagem Zig.