comptime_int em Zig — O que é e Como Usar

comptime_int em Zig — O que é e Como Usar

Definição

comptime_int é o tipo inteiro de precisão arbitrária que existe apenas em tempo de compilação. Quando você escreve um literal inteiro como 42 ou 1_000_000 em Zig, ele é inicialmente do tipo comptime_int. Esse tipo não tem limite de tamanho — pode representar qualquer valor inteiro, por maior que seja — e nunca sofre overflow.

O comptime_int existe apenas durante a compilação. Antes de o código ser executado, ele deve ser convertido (explícita ou implicitamente) para um tipo concreto como u32, i64 ou usize.

Por que comptime_int Importa

  1. Sem overflow em comptime: Cálculos em tempo de compilação nunca perdem precisão.
  2. Literais flexíveis: Um literal como 42 pode ser atribuído a qualquer tipo inteiro que o comporte, sem cast explícito.
  3. Metaprogramação: Permite operações matemáticas complexas durante a compilação sem preocupação com limites de bits.
  4. Segurança: O compilador verifica se o valor cabe no tipo de destino antes de gerar código.

Exemplo Prático

Literais Inteiros e Coerção Automática

const std = @import("std");

pub fn main() void {
    // 42 é comptime_int, convertido implicitamente para cada tipo
    const a: u8 = 42;
    const b: u32 = 42;
    const c: i64 = 42;
    const d: usize = 42;

    std.debug.print("u8={}, u32={}, i64={}, usize={}\n", .{ a, b, c, d });
}

Cálculos de Precisão Arbitrária em Comptime

const std = @import("std");

const fatorial_20 = blk: {
    var resultado: comptime_int = 1;
    for (1..21) |i| {
        resultado *= i;
    }
    break :blk resultado;
};

pub fn main() void {
    // fatorial_20 = 2432902008176640000
    // Cabe em u64, então a conversão é segura
    const valor: u64 = fatorial_20;
    std.debug.print("20! = {}\n", .{valor});
}

Erro de Compilação: Valor Não Cabe no Tipo

const std = @import("std");

pub fn main() void {
    // ERRO de compilação: 256 não cabe em u8 (máximo é 255)
    // const x: u8 = 256;

    // OK: 255 cabe em u8
    const x: u8 = 255;
    std.debug.print("{}\n", .{x});
}

comptime_int vs Tipos Concretos

Característicacomptime_intu32, i64, etc.
PrecisãoArbitrária (ilimitada)Fixa (N bits)
OverflowImpossívelDetectado em safe mode
Existe em runtimeNuncaSim
Uso direto em structsApenas em comptimeSim
Operações de I/ONãoSim

Uso em Funções Genéricas

comptime_int é especialmente útil em funções genéricas que recebem parâmetros numéricos comptime. O compilador usa a precisão arbitrária para validar a escolha de tipo antes de gerar código:

const std = @import("std");

fn arrayDeTamanho(comptime n: comptime_int) [n]u8 {
    // n é avaliado em comptime — pode ser usado como tamanho de array
    var resultado: [n]u8 = undefined;
    for (0..n) |i| {
        resultado[i] = @intCast(i % 256);
    }
    return resultado;
}

pub fn main() void {
    const arr = arrayDeTamanho(8);
    std.debug.print("Array: {any}\n", .{arr});
}

Perguntas Frequentes

Por que Zig usa comptime_int em vez de inferir direto para i32? Porque um literal como 1_000_000_000_000 não caberia em i32, mas cabe em i64. Ao manter o tipo como comptime_int até o ponto de uso, o compilador pode escolher o tipo concreto correto sem perda de precisão.

comptime_int e comptime_float são a mesma coisa? Não. comptime_int é para literais inteiros (sem ponto decimal); comptime_float é para literais com ponto decimal como 3.14. O comptime_float usa 128 bits de precisão internamente.

Posso somar um comptime_int com um u32? Sim, mas o resultado é u32. O valor comptime é convertido implicitamente, e o compilador verifica se o valor cabe no tipo antes da conversão.

Armadilhas Comuns

  • Não pode existir em runtime: Uma variável var x: comptime_int = 42; só é válida em contexto comptime. Em funções normais, o tipo deve ser concreto.
  • Divisão em comptime: Divisão de comptime_int é exata. Dividir 7 por 2 resulta em erro se o resultado não for inteiro — use @divFloor ou @divTrunc para controlar o comportamento.
  • Confundir com bigint: comptime_int não é um tipo de runtime como BigInteger em Java. Ele desaparece após a compilação.

Termos Relacionados

  • comptime_float — Tipo float de alta precisão em comptime
  • Comptime — Execução em tempo de compilação
  • Type Coercion — Regras de conversão automática de tipos
  • usize — Tipo inteiro nativo para índices

Tutoriais Relacionados

Continue aprendendo Zig

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