---
title: "Unreachable em Zig — O que é e Como Usar"
url: "https://ziglang.com.br/glossario/unreachable-em-zig-o-que-%C3%A9-e-como-usar/"
markdown_url: "https://ziglang.com.br/glossario/unreachable-em-zig-o-que-%C3%A9-e-como-usar.MD"
description: "Entenda unreachable em Zig: o marcador para código que nunca deveria executar. Otimização, segurança e uso correto. Guia completo em pt-BR."
date: "2026-02-21"
author: "Zig Brasil"
---

# Unreachable em Zig — O que é e Como Usar

Entenda unreachable em Zig: o marcador para código que nunca deveria executar. Otimização, segurança e uso correto. Guia completo em pt-BR.


# 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

```zig
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

```zig
// 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

```zig
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

```zig
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 `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

- [Undefined](/glossario/undefined/) — Valor não inicializado
- [noreturn](/glossario/noreturn/) — Tipo de funções que nunca retornam
- [Release Modes](/glossario/release-modes/) — Modos de compilação
- [Error Union](/glossario/error-union/) — Tipos que podem conter erros

## Quando Usar unreachable vs. @panic

A escolha entre `unreachable` e `@panic` depende da natureza da condição:

```zig
// unreachable: para casos matematicamente impossíveis dado o sistema de tipos
fn descricaoDia(dia: u3) []const u8 {
    return switch (dia) {
        0 => "Domingo",
        1 => "Segunda",
        2 => "Terça",
        3 => "Quarta",
        4 => "Quinta",
        5 => "Sexta",
        6 => "Sábado",
        7 => unreachable, // u3 pode ser 7, mas semanticamente impossível
    };
}

// @panic: para erros de programação que podem ocorrer em prática
fn buscarUsuario(id: u32, usuarios: []const Usuario) Usuario {
    for (usuarios) |u| {
        if (u.id == id) return u;
    }
    // Isso PODE acontecer se o chamador passar um ID inválido
    @panic("buscarUsuario: ID não encontrado — verifique o chamador");
}

// error: para condições esperadas que devem ser tratadas
fn abrirArquivo(path: []const u8) !std.fs.File {
    return std.fs.cwd().openFile(path, .{});
}
```

A regra geral: use `unreachable` apenas quando o compilador poderia provar que o código é inalcançável, mas não consegue (por limitações do sistema de tipos). Para qualquer outra condição de erro, prefira `@panic` com mensagem descritiva ou error unions.

## Otimizações Habilitadas por unreachable

Em ReleaseFast, quando o compilador tem garantia de que um branch é `unreachable`, ele pode:

- Eliminar o branch completamente do código gerado
- Assumir que determinados valores estão dentro de um range específico
- Propagar essa informação para outras partes do código, habilitando otimizações em cadeia

Isso torna `unreachable` uma ferramenta poderosa para comunicar invariantes ao compilador em código de performance crítica.

## Comparação com Outras Linguagens

Em Rust, o macro `unreachable!()` gera um panic em todos os modos. O equivalente ao `unreachable` do Zig em ReleaseFast seria `std::hint::unreachable_unchecked()` no unsafe Rust — que é explicitamente unsafe. Em C, `__builtin_unreachable()` (GCC/Clang) tem semântica similar ao `unreachable` do Zig em Release: comportamento indefinido sem verificação em runtime. O Zig diferencia-se por ser seguro por padrão (panic em Debug/ReleaseSafe) e otimizado apenas quando explicitamente solicitado via modo de release.

## Tutoriais Relacionados

- [Introdução ao Zig](/tutoriais/introducao-ao-zig/)
- [Zig Segurança de Memória](/tutoriais/zig-seguranca-memoria/)
- [Zig Debugging](/tutoriais/zig-debugging/)
