noreturn em Zig — O que é e Como Usar
Definição
noreturn é um tipo especial em Zig que indica que uma expressão ou função nunca retorna ao chamador. Quando uma função tem tipo de retorno noreturn, o compilador sabe que o fluxo de execução nunca continuará após a chamada. Isso permite otimizações e garante que código morto após chamadas noreturn seja detectado.
Exemplos de expressões noreturn incluem @panic(), std.process.exit(), unreachable e loops infinitos (while (true) {}).
Por que noreturn Importa
- Otimização: O compilador pode eliminar código após chamadas noreturn.
- Correção: Branches em switch/if que terminam com noreturn não precisam produzir valor.
- Coerção:
noreturnpode ser coagido para qualquer tipo, permitindo uso flexível em expressões. - Documentação: Deixa explícito que uma função encerra o programa ou nunca termina.
Exemplo Prático
Função que Nunca Retorna
const std = @import("std");
fn falha_fatal(mensagem: []const u8) noreturn {
std.debug.print("ERRO FATAL: {s}\n", .{mensagem});
std.process.exit(1);
}
pub fn main() void {
const config = carregarConfig() orelse
falha_fatal("Não foi possível carregar configuração");
std.debug.print("Config: {s}\n", .{config});
}
fn carregarConfig() ?[]const u8 {
return "config.json";
}
noreturn em Switch
const std = @import("std");
const Comando = enum { iniciar, parar, sair };
fn executar(cmd: Comando) void {
const mensagem: []const u8 = switch (cmd) {
.iniciar => "Iniciando...",
.parar => "Parando...",
.sair => {
std.debug.print("Encerrando programa.\n", .{});
std.process.exit(0);
// noreturn: compilador sabe que este branch não produz []const u8
},
};
std.debug.print("{s}\n", .{mensagem});
}
pub fn main() void {
executar(.iniciar);
}
Loop Infinito como noreturn
const std = @import("std");
fn servidor() noreturn {
std.debug.print("Servidor iniciado.\n", .{});
while (true) {
// Processar requisições indefinidamente
// Loop infinito sem break tem tipo noreturn
}
}
Coerção de noreturn
noreturn pode ser coagido para qualquer tipo, o que é essencial para expressões condicionais:
// unreachable tem tipo noreturn, coagido para u32
const valor: u32 = if (condicao) calcular() else unreachable;
// @panic tem tipo noreturn, coagido para []const u8
const nome: []const u8 = buscar(id) orelse @panic("ID inválido");
Armadilhas Comuns
- Confundir com void:
voidretorna sem valor;noreturnnunca retorna. Uma funçãovoidtermina normalmente. - Loops com break: Um
while (true)combreakpode retornar — o tipo é determinado pelo break, não noreturn. - unreachable em safe mode:
unreachablecausa panic em modo safe. Em release mode, é undefined behavior. Use apenas quando tiver certeza de que o código é inalcançável. - Código morto: O compilador pode alertar sobre código após uma expressão noreturn, pois ele nunca será executado.
Termos Relacionados
- void — Tipo para funções que retornam sem valor
- Unreachable — Expressão noreturn para código inalcançável
- Error Union — Tratamento de erros que pode levar a panic
- Comptime — noreturn em contexto comptime