---
title: "@ptrCast em Zig — Referência e Exemplos"
url: "https://ziglang.com.br/builtins/@ptrcast-em-zig-refer%C3%AAncia-e-exemplos/"
markdown_url: "https://ziglang.com.br/builtins/@ptrcast-em-zig-refer%C3%AAncia-e-exemplos.MD"
description: "Referência completa do @ptrCast em Zig. Converta entre tipos de ponteiro para interoperabilidade e manipulação de memória. Exemplos pt-BR."
date: "2026-02-21"
author: "Zig Brasil"
---

# @ptrCast em Zig — Referência e Exemplos

Referência completa do @ptrCast em Zig. Converta entre tipos de ponteiro para interoperabilidade e manipulação de memória. Exemplos pt-BR.


# @ptrCast em Zig

O `@ptrCast` converte um ponteiro de um tipo para outro. É a forma principal de reinterpretar dados na memória através de ponteiros com tipos diferentes. Esta é uma operação potencialmente insegura — use com cuidado e apenas quando necessário (interoperabilidade com C, interpretação de dados binários, etc.).

## Sintaxe

```zig
@ptrCast(ptr: anytype) DestType
```

O tipo de destino é inferido do contexto (variável, retorno, parâmetro).

## Parâmetros

- **ptr** (`anytype`): O ponteiro a ser convertido. Deve ser um tipo de ponteiro válido.

## Valor de retorno

Retorna o ponteiro convertido para o tipo de destino inferido do contexto.

## Exemplos práticos

### Exemplo 1: Reinterpretar struct como bytes

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

const Cabecalho = packed struct {
    versao: u8,
    tipo: u8,
    tamanho: u16,
};

pub fn main() void {
    var cab = Cabecalho{
        .versao = 1,
        .tipo = 3,
        .tamanho = 256,
    };

    // Reinterpretar a struct como bytes
    const bytes: *[@sizeOf(Cabecalho)]u8 = @ptrCast(&cab);
    std.debug.print("Bytes: {any}\n", .{bytes.*});
}
```

### Exemplo 2: Interoperabilidade com C (anyopaque)

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

const MeuDado = struct {
    valor: u32,
    nome: []const u8,
};

fn callback(ctx: *anyopaque) void {
    // Converter de *anyopaque de volta para o tipo original
    const dado: *MeuDado = @ptrCast(@alignCast(ctx));
    std.debug.print("Valor: {}, Nome: {s}\n", .{ dado.valor, dado.nome });
}

pub fn main() void {
    var dado = MeuDado{ .valor = 42, .nome = "teste" };
    // Passar como *anyopaque (void* do C)
    callback(@ptrCast(&dado));
}
```

### Exemplo 3: Cast de ponteiro com vtable

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

const Base = struct {
    vtable: *const VTable,

    const VTable = struct {
        executarFn: *const fn (*anyopaque) void,
    };

    pub fn executar(self: *Base) void {
        self.vtable.executarFn(@ptrCast(self));
    }
};
```

## Quando usar @ptrCast

1. **Interop com C**: Converter `*anyopaque` (void pointer) para tipos concretos.
2. **Serialização binária**: Interpretar bytes como structs ou vice-versa.
3. **Vtables**: Converter ponteiros genéricos em callbacks.
4. **Alinhamento**: Combinado com `@alignCast` para ajustar alinhamento.

## Regras importantes

- Frequentemente combinado com `@alignCast` quando o alinhamento do ponteiro de origem não corresponde ao destino.
- Converter para um tipo incompatível e desreferenciar causa undefined behavior.
- Em modo safe (Debug/ReleaseSafe), casts inválidos são detectados em runtime.

## Segurança e verificações em runtime

Em modo **Debug** e **ReleaseSafe**, o Zig verifica alinhamento automaticamente quando `@alignCast` é usado junto com `@ptrCast`. Se o endereço do ponteiro de origem não satisfaz o alinhamento requerido pelo tipo de destino, ocorre um panic em runtime — muito mais seguro que o undefined behavior silencioso do C.

Em **ReleaseFast** e **ReleaseSmall**, as verificações de alinhamento são removidas para máximo desempenho, então cabe ao programador garantir a corretude.

## Comparação com equivalente em C

Em C, conversões de ponteiro são feitas com cast explícito e não oferecem nenhuma verificação:

```c
// C: cast silencioso, sem verificação alguma
void *ctx = get_context();
MeuDado *dado = (MeuDado *)ctx;  // pode causar UB por alinhamento ou tipo incorreto
```

Em Zig, a combinação de `@ptrCast` com `@alignCast` é explícita sobre o que está sendo feito, e o modo safe verifica o alinhamento em runtime:

```zig
// Zig: explícito e verificado em safe mode
const dado: *MeuDado = @ptrCast(@alignCast(ctx));
```

## Padrão com `@alignCast`

A combinação mais comum de `@ptrCast` é com `@alignCast` ao recuperar ponteiros tipados de APIs que usam `*anyopaque`:

```zig
// Padrão correto ao recuperar contexto de callback
fn meuCallback(ctx: *anyopaque) void {
    // @alignCast verifica o alinhamento em runtime (safe mode)
    // @ptrCast converte o tipo do ponteiro
    const dado: *MinhStruct = @ptrCast(@alignCast(ctx));
    _ = dado;
}
```

Se o tipo de destino tiver alinhamento igual ou menor que `*anyopaque` (que é alinhamento 1), o `@alignCast` pode ser omitido, mas é boa prática mantê-lo para documentar a intenção.

## Erros comuns

**1. Esquecer `@alignCast` ao converter de `*anyopaque`:**
```zig
// PODE CAUSAR PROBLEMA: sem verificação de alinhamento
const dado: *MeuTipo = @ptrCast(ctx); // aviso do compilador em versões recentes

// CORRETO: combinar com @alignCast
const dado: *MeuTipo = @ptrCast(@alignCast(ctx));
```

**2. Confundir `@ptrCast` com `@bitCast`:**
- `@ptrCast`: converte o **tipo do ponteiro**, sem mover dados.
- `@bitCast`: reinterpreta os **bits de um valor**, sem ponteiros.

**3. Usar `@ptrCast` para converter valores, não ponteiros:**
```zig
// ERRADO: @ptrCast é apenas para ponteiros
// const x: u32 = @ptrCast(meu_float); // erro de compilação

// CORRETO para valores: usar @bitCast ou @as
const x: u32 = @bitCast(meu_float);
```

## Perguntas Frequentes

**P: Quando devo usar `@ptrCast` versus `@as`?**

R: Use `@as` para coerções de tipo seguras entre tipos compatíveis (ex: `u8` para `u16`). Use `@ptrCast` exclusivamente para converter entre tipos de ponteiro — quando você precisa reinterpretar a memória apontada como um tipo diferente.

**P: `@ptrCast` pode converter entre ponteiros de tamanhos diferentes, como `*u8` e `[]u8`?**

R: Não. `@ptrCast` converte ponteiros simples (`*T`) entre si. Para converter entre ponteiros e slices, ou ponteiros com sentinela, use `@as` com os tipos adequados ou construa o slice manualmente com `ptr[0..len]`.

**P: É seguro usar `@ptrCast` para serialização binária de structs?**

R: Apenas com `packed struct`. Structs normais podem ter padding inserido pelo compilador, tornando a interpretação byte a byte imprevisível. Com `packed struct`, o layout é garantido e o cast é seguro.

## Builtins relacionados

- [@alignCast](/builtins/align-cast/) — Ajustar alinhamento do ponteiro
- [@constCast](/builtins/const-cast/) — Remover qualificador const
- [@volatileCast](/builtins/volatile-cast/) — Remover qualificador volatile
- [@as](/builtins/as/) — Conversão de tipo segura (coerção)
- [@intFromPtr](/builtins/int-from-ptr/) — Converter ponteiro para inteiro
- [@ptrFromInt](/builtins/ptr-from-int/) — Converter inteiro para ponteiro

## Tutoriais relacionados

- [Ponteiros em Zig](/tutoriais/ponteiros-zig/)
- [Interoperabilidade com C](/tutoriais/interop-c/)
- [Gerenciamento de Memória em Zig](/tutoriais/gerenciamento-de-memoria-zig/)
