---
title: "@compileError em Zig — Referência e Exemplos"
url: "https://ziglang.com.br/builtins/@compileerror-em-zig-refer%C3%AAncia-e-exemplos/"
markdown_url: "https://ziglang.com.br/builtins/@compileerror-em-zig-refer%C3%AAncia-e-exemplos.MD"
description: "Referência completa do @compileError em Zig. Aprenda a gerar erros de compilação personalizados com exemplos práticos em português."
date: "2026-02-21"
author: "Zig Brasil"
---

# @compileError em Zig — Referência e Exemplos

Referência completa do @compileError em Zig. Aprenda a gerar erros de compilação personalizados com exemplos práticos em português.


# @compileError em Zig

O `@compileError` gera um erro de compilação com uma mensagem personalizada. É usado principalmente em código genérico e metaprogramação para rejeitar tipos ou configurações inválidos em tempo de compilação, antes que o programa seja executado. Esse mecanismo garante que problemas sejam detectados o mais cedo possível.

## Sintaxe

```zig
@compileError(comptime msg: []const u8) noreturn
```

## O que faz

O `@compileError` interrompe a compilação e exibe a mensagem fornecida como erro. O compilador aponta exatamente a linha onde o `@compileError` foi invocado, facilitando a identificação do problema. Esse builtin é especialmente poderoso em branches de `switch` ou `if` em comptime que representam caminhos de código inválidos.

## Parâmetros

- **msg** (`[]const u8`, comptime): A mensagem de erro a ser exibida pelo compilador. Deve ser uma string conhecida em tempo de compilação. Pode ser construída por concatenação de strings literais.

## Valor de retorno

O tipo de retorno é `noreturn` — a compilação é interrompida e nenhum valor é produzido.

## Exemplos práticos

### Exemplo 1: Validação de tipos em funções genéricas

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

fn somar(a: anytype, b: anytype) @TypeOf(a, b) {
    const T = @TypeOf(a, b);
    const info = @typeInfo(T);

    switch (info) {
        .int, .comptime_int => return a + b,
        .float, .comptime_float => return a + b,
        else => @compileError(
            "somar() requer tipos numéricos, recebeu: " ++ @typeName(T),
        ),
    }
}

test "somar numéricos" {
    try std.testing.expect(somar(@as(i32, 10), @as(i32, 20)) == 30);
    try std.testing.expect(somar(@as(f64, 1.5), @as(f64, 2.5)) == 4.0);

    // A linha abaixo geraria erro de compilação:
    // _ = somar("hello", "world");
    // Erro: somar() requer tipos numéricos, recebeu: *const [5:0]u8
}
```

### Exemplo 2: Restrições de plataforma

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

fn funcaoApenasLinux() void {
    if (builtin.os.tag != .linux) {
        @compileError("Esta função só é suportada em Linux");
    }
    // Implementação específica de Linux...
}

fn funcaoApenas64Bits() void {
    if (@sizeOf(usize) != 8) {
        @compileError("Esta função requer uma arquitetura de 64 bits");
    }
    // Implementação que depende de ponteiros de 64 bits...
}
```

### Exemplo 3: Validação de campos de struct em comptime

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

fn validarModelo(comptime T: type) void {
    const info = @typeInfo(T);
    if (info != .@"struct") {
        @compileError("validarModelo requer uma struct, recebeu: " ++ @typeName(T));
    }

    const fields = info.@"struct".fields;

    // Verificar que a struct tem campo "id"
    comptime {
        var tem_id = false;
        for (fields) |f| {
            if (std.mem.eql(u8, f.name, "id")) {
                tem_id = true;
                break;
            }
        }
        if (!tem_id) {
            @compileError(@typeName(T) ++ " deve ter um campo 'id'");
        }
    }
}

const Usuario = struct {
    id: u64,
    nome: []const u8,
};

// Isso compila normalmente
comptime {
    validarModelo(Usuario);
}

// const Invalido = struct { nome: []const u8 };
// validarModelo(Invalido); // Erro: Invalido deve ter um campo 'id'
```

## Casos de uso comuns

1. **Validação de tipos genéricos**: Rejeitar tipos que não satisfazem os requisitos de uma função ou struct genérica.
2. **Restrições de plataforma**: Impedir compilação em plataformas não suportadas.
3. **Funcionalidade não implementada**: Marcar caminhos de código que ainda não foram implementados, diferente de `@panic` que ocorre em runtime.
4. **Validação de constantes**: Verificar que constantes de configuração têm valores válidos.
5. **API segura**: Guiar desenvolvedores com mensagens de erro claras quando usam uma API incorretamente.

## Diferença entre @compileError e @panic

- `@compileError` interrompe a **compilação** — o programa nunca chega a ser executado.
- `@panic` interrompe a **execução** — o programa compila mas falha ao encontrar o panic em runtime.

Use `@compileError` quando o erro pode ser detectado estaticamente. Use `@panic` para erros que só podem ser detectados em tempo de execução.

## Construindo mensagens de erro informativas

A mensagem de `@compileError` pode ser construída por concatenação de strings literais e `@typeName`:

```zig
fn requerInteiro(comptime T: type) void {
    const info = @typeInfo(T);
    if (info != .int and info != .comptime_int) {
        @compileError(
            "Esperado tipo inteiro, recebeu '" ++
            @typeName(T) ++
            "'. Use tipos como u8, i32, u64."
        );
    }
}
```

A mensagem aparece exatamente no ponto onde `@compileError` é chamado, com o stack de chamadas comptime:

```
src/lib.zig:5:9: error: Esperado tipo inteiro, recebeu 'f32'. Use tipos como u8, i32, u64.
```

## @compileError em blocos comptime

`@compileError` é especialmente útil dentro de blocos `comptime` e `inline for` para validações complexas:

```zig
const Protocolo = struct {
    versao: u8,
    flags: u16,
    payload_len: u32,
};

comptime {
    // Verificar que o protocolo tem o tamanho esperado para o wire format
    if (@sizeOf(Protocolo) != 7) {
        @compileError(
            "Protocolo deve ter 7 bytes no wire format, mas tem " ++
            std.fmt.comptimePrint("{}", .{@sizeOf(Protocolo)}) ++
            " bytes. Verifique o layout."
        );
    }
}
```

## Equivalente em C

Em C, `_Static_assert` (C11) é o equivalente mais próximo:

```c
_Static_assert(sizeof(struct Protocolo) == 7, "Tamanho incorreto");
```

A diferença: `_Static_assert` tem mensagem estática. `@compileError` permite mensagens dinâmicas construídas com `@typeName`, `@tagName` e concatenação de strings comptime.

## Padrão "else unreachable"

Um padrão comum é usar `@compileError` na branch `else` de um switch sobre tipos:

```zig
fn serializar(comptime T: type, valor: T) []const u8 {
    return switch (@typeInfo(T)) {
        .int => serializarInt(valor),
        .float => serializarFloat(valor),
        .bool => if (valor) "true" else "false",
        else => @compileError("Tipo não suportado para serialização: " ++ @typeName(T)),
    };
}
```

Isso garante que novos tipos precisem de implementação explícita — o compilador rejeita código que usa a função com tipos não suportados.

## Erros comuns

**Usar `@compileError` fora de contexto comptime com condição runtime**: Se a condição que leva ao `@compileError` não for resolvível em comptime, o compilador emitirá um erro diferente — sobre variável runtime em contexto comptime.

**String não-comptime na mensagem**: A mensagem deve ser uma string literal ou concatenação de strings/valores comptime. Não pode ser uma string dinâmica de runtime.

## Perguntas Frequentes

**Posso usar `std.fmt.comptimePrint` para formatar a mensagem?**

Sim! `std.fmt.comptimePrint` formata strings em comptime e pode ser concatenado na mensagem:

```zig
@compileError("Tamanho máximo é " ++ std.fmt.comptimePrint("{}", .{MAX}) ++ " bytes");
```

**@compileError afeta o desempenho do binário?**

Não. Se `@compileError` é atingido, a compilação falha e nenhum binário é gerado. Se não é atingido, não existe no código gerado — zero custo em runtime.

## Builtins relacionados

- [@compileLog](/builtins/compile-log/) — Imprime valores em tempo de compilação para depuração
- [@typeName](/builtins/type-name/) — Útil para construir mensagens de erro descritivas
- [@typeInfo](/builtins/type-info/) — Inspeciona tipos para validação
- [@hasField](/builtins/has-field/) — Verifica existência de campos
- [@hasDecl](/builtins/has-decl/) — Verifica existência de declarações

## Tutoriais relacionados

- [Metaprogramação com comptime](/tutoriais/comptime/)
- [Programação genérica em Zig](/tutoriais/generics/)
- [Boas práticas de API](/tutoriais/api-design/)
