@bitSizeOf em Zig
O @bitSizeOf retorna o tamanho de um tipo em bits, sem incluir padding de alinhamento. Diferente de @sizeOf, que retorna bytes incluindo padding, @bitSizeOf retorna a quantidade exata de bits que compõem o tipo. Isso é particularmente útil ao trabalhar com tipos de bits não-padrão como u3, u24 ou i12.
Sintaxe
@bitSizeOf(comptime T: type) comptime_int
O que faz
O @bitSizeOf consulta a quantidade exata de bits que um tipo usa para representar seus dados, sem considerar bytes de padding adicionados para alinhamento. Para tipos padrão como u32, o resultado é simplesmente 32. Para tipos como u24, retorna 24 (enquanto @sizeOf retornaria 4 bytes = 32 bits, incluindo padding).
Parâmetros
- T (
type, comptime): O tipo cujo tamanho em bits será consultado.
Valor de retorno
Retorna um comptime_int representando o número exato de bits do tipo.
Exemplos práticos
Exemplo 1: Comparação com @sizeOf
const std = @import("std");
test "bitSizeOf vs sizeOf" {
// Para tipos alinhados, bitSizeOf == sizeOf * 8
try std.testing.expect(@bitSizeOf(u8) == 8);
try std.testing.expect(@bitSizeOf(u16) == 16);
try std.testing.expect(@bitSizeOf(u32) == 32);
try std.testing.expect(@bitSizeOf(u64) == 64);
// Para tipos de bits arbitrários, os valores diferem
try std.testing.expect(@bitSizeOf(u24) == 24);
try std.testing.expect(@sizeOf(u24) == 4); // 4 bytes com padding
try std.testing.expect(@bitSizeOf(u3) == 3);
try std.testing.expect(@sizeOf(u3) == 1); // 1 byte mínimo
try std.testing.expect(@bitSizeOf(bool) == 1);
try std.testing.expect(@sizeOf(bool) == 1); // 1 byte mínimo
}
Exemplo 2: Packed structs e layout de bits
const std = @import("std");
const Flags = packed struct {
leitura: bool, // 1 bit
escrita: bool, // 1 bit
execucao: bool, // 1 bit
especial: bool, // 1 bit
reservado: u4, // 4 bits
};
const CorRGB565 = packed struct {
vermelho: u5, // 5 bits
verde: u6, // 6 bits
azul: u5, // 5 bits
};
test "tamanho de packed structs" {
// Packed structs empacotam campos sem padding
try std.testing.expect(@bitSizeOf(Flags) == 8);
try std.testing.expect(@sizeOf(Flags) == 1);
try std.testing.expect(@bitSizeOf(CorRGB565) == 16);
try std.testing.expect(@sizeOf(CorRGB565) == 2);
}
Exemplo 3: Cálculos de capacidade de armazenamento
const std = @import("std");
fn bitsParaArmazenar(comptime T: type, n: usize) usize {
return @bitSizeOf(T) * n;
}
fn bytesNecessarios(comptime T: type, n: usize) usize {
const total_bits = bitsParaArmazenar(T, n);
return (total_bits + 7) / 8; // Arredondar para cima
}
test "cálculo de armazenamento" {
// 10 valores u12 precisam de 120 bits = 15 bytes
try std.testing.expect(bitsParaArmazenar(u12, 10) == 120);
try std.testing.expect(bytesNecessarios(u12, 10) == 15);
// 8 valores bool precisam de 8 bits = 1 byte
try std.testing.expect(bitsParaArmazenar(bool, 8) == 8);
try std.testing.expect(bytesNecessarios(bool, 8) == 1);
// 3 valores u3 precisam de 9 bits = 2 bytes
try std.testing.expect(bitsParaArmazenar(u3, 3) == 9);
try std.testing.expect(bytesNecessarios(u3, 3) == 2);
}
Casos de uso comuns
- Packed structs: Verificar o tamanho exato de campos empacotados para protocolos binários.
- Formatos de imagem: Trabalhar com formatos de cor como RGB565 (16 bits) ou RGB555 (15 bits).
- Compressão de dados: Calcular o espaço mínimo necessário para armazenar dados com tipos de bits arbitrários.
- Protocolos de comunicação: Definir e verificar layouts de bits em cabeçalhos de protocolo.
- Hardware e registradores: Validar que campos de registradores packed ocupam a quantidade correta de bits.
Diferença entre @bitSizeOf e @sizeOf — resumo visual
Tipo: u24
@bitSizeOf(u24) = 24 ← bits reais do valor
@sizeOf(u24) = 4 ← bytes em memória (inclui 8 bits de padding)
Tipo: bool
@bitSizeOf(bool) = 1 ← apenas 1 bit de informação
@sizeOf(bool) = 1 ← mas ocupa 1 byte completo em memória
Tipo: packed struct { a: u3, b: u5 }
@bitSizeOf(T) = 8 ← 3 + 5 = 8 bits exatos
@sizeOf(T) = 1 ← 8 bits = 1 byte, sem padding
Equivalente em C
C não tem equivalente direto para @bitSizeOf. O sizeof do C corresponde ao @sizeOf do Zig (em bytes com padding). Para bit fields do C, o tamanho individual de cada campo não é acessível portavelmente:
// C: sizeof retorna bytes com padding
struct Flags {
unsigned leitura : 1;
unsigned escrita : 1;
unsigned execucao : 1;
unsigned reservado: 5;
};
// sizeof(struct Flags) == 4 (int, não 1 byte!)
Em Zig, usando packed struct, o comportamento é mais previsível e @bitSizeOf reflete os bits reais.
Uso com tipos de bits arbitrários
Zig suporta inteiros de qualquer largura de 0 a 65535 bits. O @bitSizeOf é essencial para trabalhar com esses tipos:
// Tipos de bits não-padrão
@bitSizeOf(u1) // 1
@bitSizeOf(u3) // 3
@bitSizeOf(u7) // 7
@bitSizeOf(u12) // 12
@bitSizeOf(u100) // 100
@bitSizeOf(u128) // 128
// Para esses tipos, @sizeOf arredonda para cima
@sizeOf(u1) // 1 (1 byte mínimo)
@sizeOf(u7) // 1
@sizeOf(u9) // 2
@sizeOf(u100) // 16
Erros comuns
Usar @bitSizeOf quando precisa de @sizeOf para memcpy: Para operações de cópia de memória, você precisa de bytes, não bits. Use @sizeOf nesses casos.
Assumir que @bitSizeOf é sempre múltiplo de 8: Para tipos como u3 ou bool, @bitSizeOf retorna valores que não são múltiplos de 8. Se você precisar converter para bytes, arredonde para cima: (@bitSizeOf(T) + 7) / 8.
Perguntas Frequentes
@bitSizeOf funciona com structs normais (não packed)?
Sim, mas para structs normais o resultado é @sizeOf(T) * 8 — inclui os bits de padding. O valor mais útil de @bitSizeOf é com packed struct, onde não há padding.
Posso usar @bitSizeOf em tempo de compilação?
Sim. O resultado é sempre um comptime_int, disponível em qualquer contexto comptime. É frequentemente usado para calcular deslocamentos e tamanhos em manipulação de protocolos binários.
@bitSizeOf de u0 é zero?
Sim. @bitSizeOf(u0) == 0. Zig suporta o tipo u0, que tem apenas um valor possível (zero) e ocupa zero bits. É útil em código genérico onde um campo pode não existir.
Builtins relacionados
- @sizeOf — Retorna o tamanho em bytes (com padding)
- @alignOf — Retorna o alinhamento do tipo
- @typeInfo — Informações completas sobre o tipo
- @bitReverse — Inverte a ordem dos bits