@alignCast em Zig — Referência e Exemplos

@alignCast em Zig

O @alignCast converte um ponteiro para ter um alinhamento diferente. É necessário quando você precisa converter ponteiros entre tipos com requisitos de alinhamento distintos — por exemplo, ao converter *anyopaque (alinhamento 1) para *u32 (alinhamento 4). Em modo safe, verifica em runtime se o endereço realmente está alinhado corretamente.

Sintaxe

@alignCast(ptr: anytype) DestType

O alinhamento de destino é inferido do contexto.

Parâmetros

  • ptr (anytype): Ponteiro cujo alinhamento será convertido.

Valor de retorno

Retorna o ponteiro com o novo alinhamento. Em modo Debug/ReleaseSafe, causa panic se o endereço não estiver alinhado.

Exemplos práticos

Exemplo 1: Converter *anyopaque para tipo alinhado

const std = @import("std");

fn callback(ctx: *anyopaque) void {
    // *anyopaque tem alinhamento 1
    // *u32 requer alinhamento 4
    // @alignCast garante compatibilidade
    const ptr: *u32 = @ptrCast(@alignCast(ctx));
    std.debug.print("Valor: {}\n", .{ptr.*});
}

pub fn main() void {
    var valor: u32 = 42;
    callback(@ptrCast(&valor));
}

Exemplo 2: Combinando @ptrCast e @alignCast

const std = @import("std");

const Sensor = struct {
    id: u32,
    temperatura: f32,
};

fn processar(dados: [*]u8) void {
    // Converter bytes para ponteiro de struct com alinhamento correto
    const sensor: *Sensor = @ptrCast(@alignCast(dados));
    std.debug.print("Sensor {}: {d:.1}°C\n", .{ sensor.id, sensor.temperatura });
}

pub fn main() void {
    var sensor = Sensor{ .id = 1, .temperatura = 25.5 };
    const bytes: [*]u8 = @ptrCast(&sensor);
    processar(bytes);
}

Exemplo 3: Slice com alinhamento customizado

const std = @import("std");

fn processarAlinhado(dados: []align(16) u8) void {
    std.debug.print("Dados alinhados a 16 bytes: {} bytes\n", .{dados.len});
}

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

    // Alocar com alinhamento específico
    const dados = try gpa.allocator().alignedAlloc(u8, 16, 64);
    defer gpa.allocator().free(dados);

    @memset(dados, 0);
    processarAlinhado(dados);
}

Casos de uso comuns

  1. Callbacks de C: Converter *anyopaque (void*) para ponteiros tipados.
  2. Serialização: Interpretar buffers de bytes como structs alinhadas.
  3. SIMD: Garantir alinhamento para instruções vetoriais.
  4. Memory-mapped I/O: Acessar registradores de hardware com alinhamento correto.

Builtins relacionados

  • @ptrCast — Conversão entre tipos de ponteiro
  • @alignOf — Consultar alinhamento de um tipo
  • @constCast — Remover qualificador const
  • @as — Conversão de tipo segura

Tutoriais relacionados

Continue aprendendo Zig

Explore mais tutoriais e artigos em português para dominar a linguagem Zig.