Unreachable em Zig — O que é e Como Usar
Definição
unreachable em Zig é uma expressão que indica ao compilador que determinado ponto do código nunca deveria ser alcançado durante a execução. Se o programa chegar a um unreachable em modo Debug ou ReleaseSafe, será emitido um panic com mensagem de erro. Em ReleaseFast e ReleaseSmall, o compilador assume que aquele ponto é verdadeiramente inalcançável e usa essa informação para otimizações agressivas.
O tipo de unreachable é noreturn — ele nunca produz um valor.
Por que Unreachable Importa
- Documentação de intenção: Comunica que certo caminho não é esperado.
- Otimização: O compilador pode eliminar branches e simplificar código.
- Detecção de bugs: Em Debug, alcançar
unreachablecausa panic imediato. - Exaustividade: Permite completar switches sem tratar casos impossíveis.
Exemplo Prático
Em Switch Statements
const std = @import("std");
fn diaDaSemana(numero: u3) []const u8 {
return switch (numero) {
0 => "Domingo",
1 => "Segunda",
2 => "Terça",
3 => "Quarta",
4 => "Quinta",
5 => "Sexta",
6 => "Sábado",
7 => unreachable, // u3 vai de 0 a 7, mas só há 7 dias
};
}
Para Unwrap Seguro
// Quando SABEMOS que o optional não é null
fn primeiroElemento(slice: []const u8) u8 {
std.debug.assert(slice.len > 0);
return slice[0];
}
// Ou com error unions quando sabemos que não falha
const valor: u32 = std.fmt.parseInt(u32, "42", 10) catch unreachable;
Em Funções que Nunca Retornam
fn loopInfinito() noreturn {
while (true) {
// processa eventos...
}
// O compilador sabe que nunca chega aqui
// Sem unreachable necessário — while(true) já é noreturn
}
fn sairComErro(msg: []const u8) noreturn {
std.debug.print("ERRO FATAL: {s}\n", .{msg});
std.process.exit(1);
// Após exit(), nunca retorna
}
Eliminando Branches Impossíveis
fn dividirSeguro(a: u32, b: u32) u32 {
if (b == 0) {
sairComErro("Divisão por zero");
// sairComErro é noreturn, então o compilador sabe que
// o código abaixo só executa quando b != 0
}
return a / b;
}
Comportamento por Modo de Compilação
| Modo | Ao atingir unreachable |
|---|---|
| Debug | Panic: “reached unreachable” |
| ReleaseSafe | Panic: “reached unreachable” |
| ReleaseFast | Comportamento indefinido (UB) |
| ReleaseSmall | Comportamento indefinido (UB) |
Armadilhas Comuns
- Usar como “TODO”: Não use
unreachablecomo placeholder para código não implementado. Use@panic("TODO")em vez disso. - Assumir incorretamente: Se o
unreachablefor alcançado em Release, o programa terá comportamento indefinido — pode crashar, corromper dados ou continuar silenciosamente. - Confundir com
undefined:undefinedé para valores não inicializados;unreachableé para código que não deveria executar. - Otimização prematura: Não coloque
unreachableapenas para “ajudar” o compilador. Ele já faz essas otimizações quando possível.
Termos Relacionados
- Undefined — Valor não inicializado
- noreturn — Tipo de funções que nunca retornam
- Release Modes — Modos de compilação
- Error Union — Tipos que podem conter erros