---
title: "@constCast em Zig — Referência e Exemplos"
url: "https://ziglang.com.br/builtins/@constcast-em-zig-refer%C3%AAncia-e-exemplos/"
markdown_url: "https://ziglang.com.br/builtins/@constcast-em-zig-refer%C3%AAncia-e-exemplos.MD"
description: "Referência completa do @constCast em Zig. Remova o qualificador const de ponteiros quando necessário. Exemplos práticos pt-BR."
date: "2026-02-21"
author: "Zig Brasil"
---

# @constCast em Zig — Referência e Exemplos

Referência completa do @constCast em Zig. Remova o qualificador const de ponteiros quando necessário. Exemplos práticos pt-BR.


# @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

```zig
@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

```zig
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

```zig
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

```zig
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`.

## Por que @constCast é raramente necessário

Em código Zig puro, `@constCast` quase nunca é necessário. O sistema de tipos do Zig é projetado para que `const` seja propagado corretamente. A necessidade de `@constCast` geralmente indica um de dois cenários:

1. **API C mal projetada**: A função C deveria declarar o parâmetro como `const char*` mas não declara, por descuido ou compatibilidade histórica.
2. **Design de API a ser melhorado**: Se você está escrevendo Zig e precisa de `@constCast`, considere redesenhar a API para aceitar o tipo correto.

## Equivalente em C

Em C, `const_cast<T*>` existe apenas em C++. Em C puro, você usa um cast explícito:

```c
const char *str = "hello";
char *mutable_str = (char *)str; // C puro — sem aviso
```

O Zig é mais rigoroso: sem `@constCast`, o compilador rejeita a conversão de `*const T` para `*T`, forçando o programador a ser explícito sobre a intenção.

## Quando @constCast é seguro

`@constCast` é seguro quando:

1. Os dados foram originalmente declarados sem `const` e você está apenas adaptando uma interface
2. A função receptora não modificará os dados (você garante isso ao ler o código)
3. O dado está em memória de leitura/escrita (não em seção `.rodata`)

```zig
// SEGURO: dados originalmente mutáveis
var buffer = [_]u8{ 1, 2, 3 };
const slice: []const u8 = &buffer; // const view de dados mutáveis
const mutavel: []u8 = @constCast(slice); // ok, original é mutável

// PERIGOSO: string literal fica em .rodata
const str = "literal";
const mut: []u8 = @constCast(str); // @constCast compila, mas...
mut[0] = 'L'; // Undefined behavior! String literal é somente leitura
```

## Verificação em modo safe

Em modo Debug e ReleaseSafe, o Zig não tem verificação automática para uso incorreto de `@constCast` — diferente de `@alignCast`. A responsabilidade de não modificar dados originalmente `const` é inteiramente do programador.

Ferramentas como AddressSanitizer podem detectar escritas em memória somente leitura em runtime.

## Erros comuns

**Usar @constCast em string literals**: String literals em Zig ficam na seção `.rodata` do binário, que é somente leitura. Modificar uma string literal após `@constCast` causa undefined behavior — tipicamente um segfault ou comportamento silenciosamente incorreto.

**Propagar @constCast desnecessariamente**: Se você precisa de `@constCast` em muitos lugares, o problema provavelmente está no design da API. Revise se as funções intermediárias devem aceitar `[]const u8` ou `[]u8`.

## Perguntas Frequentes

**@constCast funciona com slices?**

Sim. `@constCast([]const u8)` retorna `[]u8`. O Zig aplica o cast tanto ao ponteiro quanto ao tipo do slice.

**Existe @volatileCast equivalente?**

Sim, existe `@volatileCast` para remover o qualificador `volatile` de ponteiros. O uso é análogo ao `@constCast`.

**Por que o compilador Zig não avisa quando uso @constCast de forma perigosa?**

O compilador não tem como saber em tempo de compilação se os dados originalmente eram constantes em memória somente leitura ou mutáveis com view const. Essa distinção existe apenas em runtime. Por isso, a responsabilidade é do programador.

## Builtins relacionados

- [@ptrCast](/builtins/ptr-cast/) — Conversão entre tipos de ponteiro
- [@alignCast](/builtins/align-cast/) — Conversão de alinhamento
- [@volatileCast](/builtins/volatile-cast/) — Remover qualificador volatile
- [@as](/builtins/as/) — Conversão segura de tipos

## 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/)
