@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
@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
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)
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
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
- Interop com C: Converter
*anyopaque(void pointer) para tipos concretos. - Serialização binária: Interpretar bytes como structs ou vice-versa.
- Vtables: Converter ponteiros genéricos em callbacks.
- Alinhamento: Combinado com
@alignCastpara ajustar alinhamento.
Regras importantes
- Frequentemente combinado com
@alignCastquando 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.
Builtins relacionados
- @alignCast — Ajustar alinhamento do ponteiro
- @constCast — Remover qualificador const
- @volatileCast — Remover qualificador volatile
- @as — Conversão de tipo segura (coerção)
- @intFromPtr — Converter ponteiro para inteiro
- @ptrFromInt — Converter inteiro para ponteiro