noreturn em Zig — O que é e Como Usar

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

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: 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 — 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

Tutoriais Relacionados

Continue aprendendo Zig

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