@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
- Depurar metaprogramação: Verificar valores intermediários em funções comptime que geram código ou tabelas.
- Entender resolução de tipos: Inspecionar como o compilador resolve tipos em funções genéricas.
- Verificar layout de structs: Examinar campos, tamanhos e alinhamentos durante a compilação.
- Rastrear execução comptime: Entender a ordem de execução e os valores produzidos por loops e condicionais em comptime.
- Diagnóstico de erros: Quando um
@compileErroré inesperado, usar@compileLogantes dele para entender o estado.
Observações importantes
- O
@compileLogsempre 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,@compileLogopera 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