@constCast em Zig — Referência e Exemplos

@constCast em Zig

O @constCast remove o qualificador const de um ponteiro, transformando um *const T em *T. Esta operação é necessária em cenários de interoperabilidade com C ou quando uma API externa exige ponteiro mutável para dados que você sabe serem seguros de modificar. Use com cautela — modificar dados originalmente const é undefined behavior.

Sintaxe

@constCast(ptr: *const T) *T

Parâmetros

  • ptr (*const T): Ponteiro const a ser convertido para mutável.

Valor de retorno

Retorna *T — o mesmo ponteiro, agora sem a restrição de const.

Exemplos práticos

Exemplo 1: Interop com API C que exige ponteiro mutável

const std = @import("std");

// Simulação de uma função C que recebe ponteiro mutável
// mas não modifica os dados (API mal projetada)
fn funcaoC(dados: [*]u8, tamanho: usize) void {
    // Apenas lê os dados
    var soma: u64 = 0;
    for (dados[0..tamanho]) |b| {
        soma += b;
    }
    std.debug.print("Soma: {}\n", .{soma});
}

pub fn main() void {
    const mensagem = "Hello, Zig!";

    // A função C exige [*]u8, mas temos []const u8
    funcaoC(@constCast(mensagem.ptr), mensagem.len);
}

Exemplo 2: Adaptador entre APIs const e mutáveis

const std = @import("std");

fn processarMutavel(dados: []u8) void {
    // Processa sem modificar
    for (dados) |byte| {
        std.debug.print("{c}", .{byte});
    }
    std.debug.print("\n", .{});
}

fn adaptador(dados: []const u8) void {
    // Sabemos que processarMutavel não modifica os dados
    processarMutavel(@constCast(dados));
}

pub fn main() void {
    const texto: []const u8 = "Zig Brasil";
    adaptador(texto);
}

Exemplo 3: Cast de slice const

const std = @import("std");

pub fn main() void {
    const dados: []const u8 = "imutável";

    // Remover const do slice inteiro
    const mutavel: []u8 = @constCast(dados);
    _ = mutavel;

    // CUIDADO: modificar dados originalmente const é UB!
    // mutavel[0] = 'I'; // Undefined behavior!
}

Casos de uso comuns

  1. Interop com C: APIs C que recebem char* em vez de const char* mesmo sem modificar.
  2. Callbacks genéricos: Quando uma interface exige ponteiro mutável mas a implementação não modifica.
  3. Testes: Simular condições onde constness precisa ser contornada.

Regras importantes

  • Nunca modifique dados originalmente const: Se os dados foram declarados como const, modificá-los após @constCast é undefined behavior.
  • Use @constCast apenas quando tiver certeza de que a mutabilidade é segura.
  • Prefira redesenhar a API para aceitar *const T em vez de usar @constCast.

Builtins relacionados

Tutoriais relacionados

Continue aprendendo Zig

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