Unreachable em Zig — O que é e Como Usar

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

  1. Documentação de intenção: Comunica que certo caminho não é esperado.
  2. Otimização: O compilador pode eliminar branches e simplificar código.
  3. Detecção de bugs: Em Debug, alcançar unreachable causa panic imediato.
  4. 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

ModoAo atingir unreachable
DebugPanic: “reached unreachable”
ReleaseSafePanic: “reached unreachable”
ReleaseFastComportamento indefinido (UB)
ReleaseSmallComportamento indefinido (UB)

Armadilhas Comuns

  • Usar como “TODO”: Não use unreachable como placeholder para código não implementado. Use @panic("TODO") em vez disso.
  • Assumir incorretamente: Se o unreachable for 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 unreachable apenas para “ajudar” o compilador. Ele já faz essas otimizações quando possível.

Termos Relacionados

Tutoriais Relacionados

Continue aprendendo Zig

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