Comptime em Zig — O que é e Como Usar

Comptime em Zig — O que é e Como Usar

Definição

Comptime (abreviação de compile time, tempo de compilação) é um dos recursos mais poderosos e distintivos da linguagem Zig. Ele permite que código seja executado durante a compilação, não em tempo de execução. Com comptime, você pode avaliar expressões, gerar tipos, desenrolar loops e criar funções genéricas — tudo antes do programa rodar.

Diferentemente de macros em C/C++ ou templates em C++, comptime em Zig usa a mesma sintaxe da linguagem normal. Não existe uma “linguagem separada” para metaprogramação.

Por que Comptime Importa

  1. Genéricos sem custo: Funções genéricas são resolvidas em tempo de compilação, gerando código especializado.
  2. Eliminação de código morto: Condições avaliadas em comptime eliminam branches desnecessários do binário final.
  3. Validação antecipada: Erros de lógica podem ser capturados na compilação, não em produção.
  4. Zero overhead: Tudo que é resolvido em comptime não tem custo em runtime.

Exemplo Prático

Função Genérica com comptime

const std = @import("std");

fn maximo(comptime T: type, a: T, b: T) T {
    return if (a > b) a else b;
}

pub fn main() void {
    const resultado_int = maximo(u32, 10, 20);
    const resultado_float = maximo(f64, 3.14, 2.71);

    std.debug.print("Max int: {}\n", .{resultado_int});
    std.debug.print("Max float: {d}\n", .{resultado_float});
}

O parâmetro comptime T: type obriga o compilador a resolver T durante a compilação. Isso gera duas versões especializadas da função — uma para u32 e outra para f64.

Bloco comptime

const std = @import("std");

const tabela = blk: {
    var resultado: [10]u32 = undefined;
    for (0..10) |i| {
        resultado[i] = i * i;
    }
    break :blk resultado;
};

pub fn main() void {
    // tabela já contém [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
    // calculado em tempo de compilação!
    std.debug.print("5² = {}\n", .{tabela[5]});
}

Condicional em Comptime

const builtin = @import("builtin");

const separador = if (builtin.os.tag == .windows) '\\' else '/';

Aqui, o compilador avalia a condição durante a compilação e elimina completamente o branch não utilizado.

Como Funciona

Quando o compilador Zig encontra comptime:

  1. Ele executa o código durante a fase de compilação.
  2. Variáveis comptime devem ser resolvidas sem depender de valores de runtime.
  3. O resultado é “embutido” no binário como se fosse uma constante literal.
  4. Funções chamadas em contexto comptime não podem ter efeitos colaterais de runtime (I/O, alocação de heap, etc.).

Armadilhas Comuns

  • Tentar usar valores de runtime em contexto comptime: Um parâmetro comptime não pode receber um valor que só é conhecido em tempo de execução. O compilador emitirá um erro claro.
  • Loops infinitos em comptime: O compilador tem um limite de avaliação. Loops muito grandes em comptime resultam em erro de compilação.
  • Confundir const com comptime: const apenas impede reatribuição; comptime garante avaliação em tempo de compilação.
  • Efeitos colaterais: Chamar funções que fazem I/O em contexto comptime causará erro.

Termos Relacionados

  • comptime_int — Tipo inteiro de precisão arbitrária em comptime
  • comptime_float — Tipo float de alta precisão em comptime
  • anytype — Parâmetro de tipo inferido
  • Inline — Expansão inline de funções e loops

Tutoriais Relacionados

Continue aprendendo Zig

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