@compileLog em Zig — Referência e Exemplos

@compileLog em Zig

O @compileLog imprime valores em tempo de compilação, permitindo depurar código comptime. Quando presente no código, o compilador exibe os valores e gera um erro de compilação (para evitar que mensagens de debug sejam deixadas acidentalmente no código de produção).

Sintaxe

@compileLog(args: ...) void

O que faz

O @compileLog aceita qualquer número de argumentos conhecidos em tempo de compilação e os imprime durante a compilação. Os valores são exibidos com informação de tipo. Após imprimir, a compilação falha com um erro indicando que @compileLog foi encontrado — isso é intencional para garantir que chamadas de depuração não permaneçam em código final.

Parâmetros

  • args (variádico, comptime): Qualquer número de valores conhecidos em tempo de compilação. Podem ser inteiros, strings, tipos, slices e qualquer outro valor comptime.

Valor de retorno

Retorna void, mas a compilação sempre falha quando @compileLog está presente no código.

Exemplos práticos

Exemplo 1: Depurando valores comptime

const std = @import("std");

fn calcularTamanho(comptime T: type) comptime_int {
    const tamanho = @sizeOf(T);
    const alinhamento = @alignOf(T);

    // Depurar valores durante a compilação
    @compileLog("Tipo:", @typeName(T));
    @compileLog("Tamanho:", tamanho, "Alinhamento:", alinhamento);

    return tamanho;
}

// Ao compilar, o compilador mostra:
// | @compileLog output |
// | Tipo: i32          |
// | Tamanho: 4 Alinhamento: 4 |
// error: compile log statement found

Exemplo 2: Inspecionando campos de struct em comptime

const std = @import("std");

fn depurarStruct(comptime T: type) void {
    const info = @typeInfo(T);
    switch (info) {
        .@"struct" => |s| {
            @compileLog("Struct:", @typeName(T));
            @compileLog("Número de campos:", s.fields.len);

            inline for (s.fields) |campo| {
                @compileLog(
                    "  Campo:",
                    campo.name,
                    "Tipo:",
                    @typeName(campo.type),
                );
            }
        },
        else => @compileLog("Não é struct:", @typeName(T)),
    }
}

const Ponto = struct {
    x: f32,
    y: f32,
    z: f32,
};

comptime {
    depurarStruct(Ponto);
}
// Saída do compilador:
// | Struct: Ponto                     |
// | Número de campos: 3              |
// |   Campo: x Tipo: f32             |
// |   Campo: y Tipo: f32             |
// |   Campo: z Tipo: f32             |

Exemplo 3: Rastreando execução de código comptime

const std = @import("std");

fn gerarLookupTable(comptime tamanho: usize) [tamanho]u32 {
    @compileLog("Gerando tabela de tamanho:", tamanho);

    var tabela: [tamanho]u32 = undefined;
    for (0..tamanho) |i| {
        tabela[i] = @as(u32, @intCast(i)) * @as(u32, @intCast(i));

        // Depurar valores específicos (cuidado: pode gerar muita saída)
        if (i < 5) {
            @compileLog("  tabela[", i, "] =", tabela[i]);
        }
    }

    @compileLog("Tabela gerada com sucesso");
    return tabela;
}

// const tabela = comptime gerarLookupTable(100);
// Descomentar para ver a saída de depuração

Casos de uso comuns

  1. Depurar metaprogramação: Verificar valores intermediários em funções comptime que geram código ou tabelas.
  2. Entender resolução de tipos: Inspecionar como o compilador resolve tipos em funções genéricas.
  3. Verificar layout de structs: Examinar campos, tamanhos e alinhamentos durante a compilação.
  4. Rastrear execução comptime: Entender a ordem de execução e os valores produzidos por loops e condicionais em comptime.
  5. Diagnóstico de erros: Quando um @compileError é inesperado, usar @compileLog antes dele para entender o estado.

Observações importantes

  • O @compileLog sempre causa falha de compilação. Não se esqueça de removê-lo antes de finalizar o código.
  • Ele não afeta a geração de código — é puramente para depuração.
  • Diferente de std.debug.print, que funciona em runtime, @compileLog opera exclusivamente em tempo de compilação.
  • O formato da saída pode variar entre versões do compilador.

Builtins relacionados

  • @compileError — Gera erro de compilação com mensagem personalizada
  • @typeName — Obtém nome de tipo para exibição
  • @typeInfo — Inspeciona tipos em comptime
  • @src — Obtém localização no código-fonte

Tutoriais relacionados

Continue aprendendo Zig

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