---
title: "Confundir comptime vs runtime — Como Resolver em Zig"
url: "https://ziglang.com.br/erros/confundir-comptime-vs-runtime-como-resolver-em-zig/"
markdown_url: "https://ziglang.com.br/erros/confundir-comptime-vs-runtime-como-resolver-em-zig.MD"
description: "Entenda a diferença entre comptime e runtime em Zig. Veja erros comuns ao confundir os dois modos de execução e como corrigi-los."
date: "2026-02-21"
author: "Zig Brasil"
---

# Confundir comptime vs runtime — Como Resolver em Zig

Entenda a diferença entre comptime e runtime em Zig. Veja erros comuns ao confundir os dois modos de execução e como corrigi-los.


# Confundir comptime vs runtime — Como Resolver em Zig

## O Que Este Erro Significa

Um dos conceitos mais poderosos e ao mesmo tempo confusos de Zig para iniciantes é a distinção entre `comptime` (tempo de compilação) e runtime (tempo de execução). Muitos erros ocorrem quando o programador tenta usar valores de runtime em contextos que exigem comptime, ou vice-versa. O compilador reporta esses erros com mensagens como:

```
error: unable to evaluate comptime expression
```

```
error: expected comptime-known value
```

```
error: runtime value used in comptime context
```

Em Zig, `comptime` permite executar código durante a compilação, gerar tipos, otimizar caminhos de código e fazer metaprogramação — mas exige que os valores sejam conhecidos antes do programa rodar.

## Causas Comuns

### 1. Usar Variável Runtime como Tipo

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

pub fn main() void {
    var tamanho: usize = 10;
    _ = &tamanho;
    // ERRO: tamanho não é comptime — não pode ser usado como tamanho de tipo
    var array: [tamanho]u8 = undefined;
    _ = array;
}
```

### 2. Valor Runtime em switch com comptime

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

pub fn main() !void {
    const stdin = std.io.getStdIn().reader();
    var buf: [100]u8 = undefined;
    const input = try stdin.readUntilDelimiterOrEof(&buf, '\n');
    _ = input;

    // input é runtime — não pode ser usado em padrões comptime
    // const tipo = @TypeOf(input); // Isso funciona, mas...
}
```

### 3. Tentar Criar Tipo com Dados de Runtime

```zig
fn criarArray(tamanho: usize) void {
    // ERRO: tamanho é runtime, mas [N]T requer N comptime
    var arr: [tamanho]u8 = undefined;
    _ = arr;
}
```

### 4. @compileLog em Código Runtime

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

pub fn main() void {
    var x: u32 = 42;
    _ = &x;
    @compileLog(x); // ERRO: x é runtime, @compileLog precisa de comptime
}
```

### 5. Usar inline for com Valores Runtime

```zig
pub fn main() void {
    var n: usize = 5;
    _ = &n;
    // ERRO: inline for precisa de range comptime
    inline for (0..n) |i| {
        _ = i;
    }
}
```

### 6. Retornar Tipo Diferente Baseado em Condição Runtime

```zig
fn processar(modo: bool) if (modo) u32 else i32 {
    // ERRO: modo é runtime, mas o tipo de retorno precisa ser comptime
    if (modo) return 42 else return -1;
}
```

## Como Corrigir

### Solucao 1: Marcar Parâmetro como comptime

```zig
fn criarArray(comptime tamanho: usize) [tamanho]u8 {
    return [_]u8{0} ** tamanho; // OK: tamanho é comptime
}

pub fn main() void {
    var arr = criarArray(10); // 10 é comptime — OK
    arr[0] = 42;
}
```

### Solucao 2: Usar Alocação Dinâmica para Tamanhos Runtime

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

pub fn main() !void {
    var gpa = std.heap.GeneralPurposeAllocator(.{}){};
    defer _ = gpa.deinit();
    const allocator = gpa.allocator();

    var tamanho: usize = 10;
    _ = &tamanho;

    // Para tamanhos runtime, use alocação dinâmica
    const buffer = try allocator.alloc(u8, tamanho);
    defer allocator.free(buffer);

    buffer[0] = 42;
}
```

### Solucao 3: Usar comptime para Geração de Tipos

```zig
fn VetorDe(comptime T: type, comptime N: usize) type {
    return struct {
        dados: [N]T,

        const Self = @This();

        fn init() Self {
            return .{ .dados = [_]T{0} ** N };
        }

        fn get(self: *const Self, i: usize) T {
            return self.dados[i];
        }
    };
}

pub fn main() void {
    const Vec3 = VetorDe(f32, 3);
    var v = Vec3.init();
    v.dados[0] = 1.0;
    v.dados[1] = 2.0;
    v.dados[2] = 3.0;
    _ = v;
}
```

### Solucao 4: Separar Lógica Comptime e Runtime

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

// Função comptime — gera código em tempo de compilação
fn calcularFibComptime(comptime n: u32) u32 {
    if (n <= 1) return n;
    return calcularFibComptime(n - 1) + calcularFibComptime(n - 2);
}

// Função runtime — executa em tempo de execução
fn calcularFibRuntime(n: u32) u32 {
    if (n <= 1) return n;
    var a: u32 = 0;
    var b: u32 = 1;
    var i: u32 = 2;
    while (i <= n) : (i += 1) {
        const temp = a + b;
        a = b;
        b = temp;
    }
    return b;
}

pub fn main() void {
    // Comptime — resultado calculado durante compilação
    const fib_10 = comptime calcularFibComptime(10);
    std.debug.print("Fib(10) comptime: {}\n", .{fib_10});

    // Runtime — resultado calculado durante execução
    var n: u32 = 10;
    _ = &n;
    const fib_n = calcularFibRuntime(n);
    std.debug.print("Fib({}) runtime: {}\n", .{ n, fib_n });
}
```

### Solucao 5: Usar @as para Forçar Tipo Comptime

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

pub fn main() void {
    // Literal numérico é comptime
    const tamanho = 100; // comptime_int

    // @as converte para tipo concreto em comptime
    const buffer_size = @as(usize, tamanho);

    var buf: [buffer_size]u8 = undefined;
    buf[0] = 42;
    _ = buf;
}
```

### Solucao 6: Bloco comptime para Computação em Compilação

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

const tabela_lookup = comptime blk: {
    var result: [256]u8 = undefined;
    for (0..256) |i| {
        result[i] = @intCast((i * 7 + 3) % 256);
    }
    break :blk result;
};

pub fn main() void {
    // tabela_lookup é computada em tempo de compilação
    // Nenhum custo de inicialização em runtime
    std.debug.print("tabela[42] = {}\n", .{tabela_lookup[42]});
}
```

## Comptime vs Runtime: Guia Rápido

| Contexto | Comptime | Runtime |
|----------|----------|---------|
| Tamanhos de array | `[N]T` requer N comptime | Use `alloc` para runtime |
| Tipos | Tipos são SEMPRE comptime | Não existe tipo runtime |
| Parâmetros | `comptime param: T` | `param: T` |
| Condições | `if (comptime ...)` avaliado na compilação | `if (...)` avaliado na execução |
| Loops | `inline for` requer range comptime | `for` aceita runtime |
| Valores | `const x = 42` (literal) é comptime | `var x: u32 = 42` é runtime |

## Quando Usar comptime

1. **Geração de tipos**: `fn MeuTipo(comptime T: type) type`
2. **Tabelas de lookup**: `const tabela = comptime { ... }`
3. **Otimização**: unrolling de loops com `inline for`
4. **Validação**: `@compileError` para verificar condições em compilação
5. **Metaprogramação**: gerar código baseado em tipos

## Quando Usar Runtime

1. **Dados do usuário**: input, argumentos de CLI, variáveis de ambiente
2. **I/O**: leitura de arquivos, rede
3. **Alocação dinâmica**: tamanhos variáveis em runtime
4. **Estado mutável**: variáveis que mudam durante execução

## Erros Relacionados

- [Expected expression](/erros/erro-expected-expression/) — Expressão esperada
- [Type mismatch](/erros/erro-type-mismatch-assignment/) — Incompatibilidade de tipo
- [Expected type](/erros/erro-expected-type/) — Tipo esperado

## Links Úteis

- [Documentação oficial do Zig — comptime](https://ziglang.org/documentation/master/#comptime)
- [Builtins: @compileLog, @compileError, @TypeOf](/builtins/)
- [Receitas de metaprogramação](/receitas/)
- [Tutorial sobre comptime em Zig](/tutoriais/)
