---
title: "noreturn em Zig — O que é e Como Usar"
url: "https://ziglang.com.br/glossario/noreturn-em-zig-o-que-%C3%A9-e-como-usar/"
markdown_url: "https://ziglang.com.br/glossario/noreturn-em-zig-o-que-%C3%A9-e-como-usar.MD"
description: "Entenda o tipo noreturn em Zig: tipo para funções que nunca retornam. Usado com @panic, exit e loops infinitos. Guia completo pt-BR."
date: "2026-02-21"
author: "Zig Brasil"
---

# noreturn em Zig — O que é e Como Usar

Entenda o tipo noreturn em Zig: tipo para funções que nunca retornam. Usado com @panic, exit e loops infinitos. Guia completo pt-BR.


# 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

1. **Otimização**: O compilador pode eliminar código após chamadas noreturn.
2. **Correção**: Branches em switch/if que terminam com noreturn não precisam produzir valor.
3. **Coerção**: `noreturn` pode ser coagido para qualquer tipo, permitindo uso flexível em expressões.
4. **Documentação**: Deixa explícito que uma função encerra o programa ou nunca termina.

## Exemplo Prático

### Função que Nunca Retorna

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

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

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

```zig
// 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**: `void` retorna sem valor; `noreturn` nunca retorna. Uma função `void` termina normalmente.
- **Loops com break**: Um `while (true)` com `break` pode retornar — o tipo é determinado pelo break, não noreturn.
- **unreachable em safe mode**: `unreachable` causa 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](/glossario/void/) — Tipo para funções que retornam sem valor
- [Unreachable](/glossario/unreachable/) — Expressão noreturn para código inalcançável
- [Error Union](/glossario/error-union/) — Tratamento de erros que pode levar a panic
- [Comptime](/glossario/comptime/) — noreturn em contexto comptime

## noreturn em Sistemas Embarcados e Kernels

Em programação de sistemas, `noreturn` é especialmente valioso. Funções de ponto de entrada de kernels, handlers de interrupção que nunca retornam, e loops de eventos em sistemas embarcados são casos naturais para `noreturn`:

```zig
// Ponto de entrada de um sistema embarcado
pub fn main() noreturn {
    inicializarHardware();
    inicializarPerifеricos();

    // Loop principal do sistema — nunca termina
    while (true) {
        processarEventos();
        sleep();
    }
}

// Handler de erro crítico em sistema embarcado
fn erroCritico(codigo: u8) noreturn {
    // Piscar LED de erro e travar o sistema
    while (true) {
        piscarLed(codigo);
    }
}
```

## Comparação com Outras Linguagens

Em C, a função `exit()` é declarada como `_Noreturn void exit(int)` usando o atributo `_Noreturn` (C11) ou `__attribute__((noreturn))` no GCC. Em Rust, o tipo `!` (never type) é equivalente — funções que divergem têm tipo de retorno `!`. Em Zig, `noreturn` é um tipo de primeira classe, o que significa que pode ser usado em qualquer posição onde um tipo é esperado, incluindo em coerções implícitas dentro de expressões condicionais.

A vantagem do Zig é que `noreturn` integra-se naturalmente ao sistema de tipos sem sintaxe especial: um `switch` cujo branch retorna `noreturn` não precisa produzir um valor para aquele caso, e o compilador entende isso automaticamente.

## Boas Práticas

- **Use para funções de erro fatal**: Funções como `fatal(msg)` que terminam o programa são candidatas naturais a `noreturn`.
- **Prefira `@panic` a `unreachable` para erros reais**: Se uma condição não deveria acontecer mas pode acontecer em caso de bug, use `@panic` — ele gera uma mensagem de erro. `unreachable` em Release mode causa comportamento indefinido.
- **Documente loops infinitos**: Se uma função tem `noreturn` porque contém um loop infinito, documente isso claramente — é uma decisão de design importante.
- **Não force `noreturn` desnecessariamente**: O compilador infere `noreturn` automaticamente de loops infinitos sem `break` e chamadas a funções `noreturn`.

## Tutoriais Relacionados

- [Sistema de Tipos do Zig](/tutoriais/tipos/)
- [Tratamento de Erros em Zig](/tutoriais/tratamento-de-erros-em-zig/)
- [Introdução ao Zig](/tutoriais/introducao-ao-zig/)
