---
title: "@panic em Zig — Referência e Exemplos"
url: "https://ziglang.com.br/builtins/@panic-em-zig-refer%C3%AAncia-e-exemplos/"
markdown_url: "https://ziglang.com.br/builtins/@panic-em-zig-refer%C3%AAncia-e-exemplos.MD"
description: "Referência completa do @panic em Zig. Encerre a execução com mensagem de erro e stack trace. Tipo noreturn. Exemplos práticos pt-BR."
date: "2026-02-21"
author: "Zig Brasil"
---

# @panic em Zig — Referência e Exemplos

Referência completa do @panic em Zig. Encerre a execução com mensagem de erro e stack trace. Tipo noreturn. Exemplos práticos pt-BR.


# @panic em Zig

O `@panic` encerra a execução do programa imediatamente com uma **mensagem de erro** e, em modo debug, um **stack trace**. É usado para situações irrecuperáveis onde continuar a execução seria inseguro ou impossível. O tipo de retorno é `noreturn` — o compilador sabe que o fluxo nunca continua após um panic.

## Sintaxe

```zig
@panic(message: []const u8) noreturn
```

## Parâmetros

- **message** (`[]const u8`): Mensagem de erro exibida ao encerrar o programa.

## Valor de retorno

`noreturn` — a função nunca retorna. O programa é encerrado.

## Exemplos práticos

### Exemplo 1: Panic em caso de estado inválido

```zig
const std = @import("std");

const Estado = enum { ativo, pausado, finalizado };

fn processar(estado: Estado) void {
    switch (estado) {
        .ativo => std.debug.print("Processando...\n", .{}),
        .pausado => std.debug.print("Em pausa.\n", .{}),
        .finalizado => @panic("Tentativa de processar estado finalizado"),
    }
}

pub fn main() void {
    processar(.ativo);
    // processar(.finalizado); // Causaria panic!
}
```

### Exemplo 2: Coerção noreturn em expressões

```zig
const std = @import("std");

fn buscarConfig(chave: []const u8) []const u8 {
    const configs = [_]struct { k: []const u8, v: []const u8 }{
        .{ .k = "host", .v = "localhost" },
        .{ .k = "porta", .v = "8080" },
    };

    for (configs) |c| {
        if (std.mem.eql(u8, c.k, chave)) return c.v;
    }

    // @panic tem tipo noreturn, coercível para []const u8
    @panic("Configuração obrigatória não encontrada");
}

pub fn main() void {
    const host = buscarConfig("host");
    std.debug.print("Host: {s}\n", .{host});
}
```

### Exemplo 3: Validação de pré-condições

```zig
const std = @import("std");

const MatrizQuadrada = struct {
    dados: []f64,
    tamanho: usize,

    pub fn init(dados: []f64) MatrizQuadrada {
        const n = std.math.sqrt(@as(f64, @floatFromInt(dados.len)));
        const tamanho: usize = @intFromFloat(n);

        if (tamanho * tamanho != dados.len) {
            @panic("Dados não formam uma matriz quadrada");
        }

        return .{ .dados = dados, .tamanho = tamanho };
    }

    pub fn get(self: MatrizQuadrada, linha: usize, coluna: usize) f64 {
        if (linha >= self.tamanho or coluna >= self.tamanho) {
            @panic("Índice fora dos limites da matriz");
        }
        return self.dados[linha * self.tamanho + coluna];
    }
};
```

## Quando usar @panic

1. **Invariantes violados**: Quando uma condição que deveria ser impossível ocorre.
2. **Configuração ausente**: Recursos obrigatórios que não podem ter fallback.
3. **Bugs**: Situações que indicam bug no código, não erro do usuário.
4. **Protótipos**: Placeholder temporário para lógica não implementada.

## Quando NÃO usar @panic

- Para erros esperados (use error unions e `try`/`catch`).
- Para validação de entrada do usuário (retorne erro).
- Para condições que podem ser tratadas graciosamente.

## Comportamento por modo de compilação

O comportamento de `@panic` varia conforme o modo de otimização escolhido:

- **Debug** e **ReleaseSafe**: Imprime a mensagem de panic e um stack trace completo no stderr, depois encerra com código de saída não-zero.
- **ReleaseFast** e **ReleaseSmall**: O stack trace pode ser omitido para reduzir tamanho do binário, mas a mensagem ainda é exibida.
- **Freestanding** (bare metal): O panic chama a função `panic` definida no root module. Pode ser customizado para piscar um LED de erro, reiniciar o sistema, etc.

## Customizando o handler de panic

É possível substituir o comportamento padrão de panic definindo uma função `panic` no arquivo raiz do projeto:

```zig
// main.zig ou root.zig
const std = @import("std");

pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace, ret_addr: ?usize) noreturn {
    _ = stack_trace;
    _ = ret_addr;
    std.log.err("PANIC CUSTOMIZADO: {s}", .{message});
    // Em embarcados, você pode reiniciar o sistema aqui
    std.process.exit(1);
}
```

Isso é especialmente útil em sistemas embarcados, onde o comportamento padrão de imprimir stack trace não é viável.

## Comparação com equivalente em C

Em C, o equivalente mais próximo é `assert()` ou `abort()`:

```c
#include <assert.h>
#include <stdlib.h>

// C: assert (desativado em release com -DNDEBUG)
assert(x > 0);

// C: abort (sempre ativo, mas sem mensagem)
if (x > 0) abort();

// C: fprintf + abort (mais próximo do @panic)
if (!(x > 0)) {
    fprintf(stderr, "x deve ser positivo\n");
    abort();
}
```

Em Zig, `@panic` é sempre ativo (não pode ser desativado por flag de compilação), fornece mensagem clara e integra com o sistema de stack trace do runtime.

## Erros comuns

**1. Usar `@panic` para erros recuperáveis:**
```zig
// ERRADO: arquivo inexistente não é bug, é condição esperada
fn lerArquivo(caminho: []const u8) []u8 {
    const arquivo = std.fs.cwd().openFile(caminho, .{}) catch
        @panic("arquivo não encontrado");
    // ...
}

// CORRETO: propagar o erro para o chamador decidir
fn lerArquivo(caminho: []const u8) ![]u8 {
    const arquivo = try std.fs.cwd().openFile(caminho, .{});
    // ...
}
```

**2. Usar `@panic` com string formatada** — `@panic` aceita apenas strings estáticas. Para mensagens dinâmicas, combine com `std.debug.panic`:

```zig
// ERRADO: @panic não formata strings
// @panic(std.fmt.allocPrint(...)); // não funciona assim

// CORRETO: usar std.debug.panic para mensagens formatadas
std.debug.panic("Valor inválido: {}", .{valor});
```

## Perguntas Frequentes

**P: Qual é a diferença entre `@panic` e `unreachable`?**

R: `unreachable` é uma asserção de que um ponto do código nunca será alcançado. Em modo Debug, gera panic com mensagem genérica "reached unreachable code". Em ReleaseFast, torna-se undefined behavior (sem verificação). `@panic` sempre termina com a mensagem fornecida, em qualquer modo.

**P: `@panic` pode ser chamado em comptime?**

R: Não diretamente. Em comptime, use `@compileError` para sinalizar erros. `@panic` é exclusivamente runtime.

**P: Como capturar um panic nos testes?**

R: O framework de testes do Zig trata panics como falhas de teste. Não há como "capturar" um panic de forma controlada — a filosofia do Zig é que panics indicam bugs que devem ser corrigidos, não tratados.

## Builtins relacionados

- [@compileError](/builtins/compile-error/) — Erro em tempo de compilação (não runtime)
- [@src](/builtins/src/) — Informações de localização para debugging
- [@compileLog](/builtins/compile-log/) — Debug em tempo de compilação

## Tutoriais relacionados

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