---
title: "@ptrFromInt em Zig — Referência e Exemplos"
url: "https://ziglang.com.br/builtins/@ptrfromint-em-zig-refer%C3%AAncia-e-exemplos/"
markdown_url: "https://ziglang.com.br/builtins/@ptrfromint-em-zig-refer%C3%AAncia-e-exemplos.MD"
description: "Referência completa do @ptrFromInt em Zig. Aprenda a converter inteiros para ponteiros com exemplos práticos em português."
date: "2026-02-21"
author: "Zig Brasil"
---

# @ptrFromInt em Zig — Referência e Exemplos

Referência completa do @ptrFromInt em Zig. Aprenda a converter inteiros para ponteiros com exemplos práticos em português.


# @ptrFromInt em Zig

O `@ptrFromInt` converte um valor inteiro (`usize`) para um ponteiro tipado. É a operação inversa de `@intFromPtr`. Este builtin é essencial para programação de sistemas, onde endereços de hardware, registradores mapeados em memória (MMIO) e tabelas de página precisam ser acessados diretamente.

## Sintaxe

```zig
@ptrFromInt(comptime T: type, endereco: usize) T
```

Na prática, o tipo de retorno é inferido pelo contexto:

```zig
const ptr: *u32 = @ptrFromInt(endereco);
```

## O que faz

O `@ptrFromInt` interpreta um valor numérico como um endereço de memória e cria um ponteiro tipado apontando para esse endereço. O compilador não verifica se o endereço é válido — essa é responsabilidade do programador.

Esta operação é considerada insegura porque não há garantia de que o endereço fornecido contenha dados válidos do tipo esperado, ou sequer que o endereço seja acessível.

## Parâmetros

- **endereco** (`usize`): O endereço de memória numérico a ser convertido para ponteiro. Deve estar alinhado conforme os requisitos do tipo de destino.

## Valor de retorno

Retorna um ponteiro do tipo especificado pelo contexto, apontando para o endereço fornecido.

## Exemplos práticos

### Exemplo 1: Acesso a registradores de hardware (MMIO)

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

// Simulação de acesso a registradores mapeados em memória
const UART_BASE: usize = 0x1000_0000;
const UART_DATA_OFFSET: usize = 0x00;
const UART_STATUS_OFFSET: usize = 0x04;

fn registradorUart(offset: usize) *volatile u32 {
    return @ptrFromInt(UART_BASE + offset);
}

fn enviarByte(byte: u8) void {
    // Escrever no registrador de dados da UART
    const reg_status = registradorUart(UART_STATUS_OFFSET);
    const reg_data = registradorUart(UART_DATA_OFFSET);

    // Esperar até que o transmissor esteja pronto
    while (reg_status.* & 0x20 != 0) {}

    // Enviar o byte
    reg_data.* = @as(u32, byte);
}
```

### Exemplo 2: Restaurando um ponteiro previamente convertido

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

fn armazenarContexto(ptr: anytype) usize {
    return @intFromPtr(ptr);
}

fn recuperarContexto(comptime T: type, endereco: usize) T {
    return @ptrFromInt(endereco);
}

test "armazenar e recuperar contexto" {
    var dados: u64 = 0xDEADBEEF;
    const endereco = armazenarContexto(&dados);

    const ptr_recuperado: *u64 = recuperarContexto(*u64, endereco);
    try std.testing.expect(ptr_recuperado.* == 0xDEADBEEF);
}
```

### Exemplo 3: Implementação de página de memória

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

const TAMANHO_PAGINA = 4096;

const Pagina = struct {
    dados: [TAMANHO_PAGINA]u8,
};

fn paginaDoEndereco(endereco: usize) *Pagina {
    // Alinhar o endereço para o início da página
    const endereco_alinhado = endereco & ~(@as(usize, TAMANHO_PAGINA - 1));
    return @ptrFromInt(endereco_alinhado);
}

fn offsetNaPagina(endereco: usize) usize {
    return endereco & (TAMANHO_PAGINA - 1);
}

test "cálculo de página" {
    const endereco: usize = 0x1234_5678;
    const offset = offsetNaPagina(endereco);
    try std.testing.expect(offset == 0x678);
}
```

## Casos de uso comuns

1. **Registradores MMIO**: Acessar periféricos de hardware mapeados em endereços fixos de memória.
2. **Desenvolvimento de sistemas operacionais**: Manipular tabelas de página, IDT, GDT e outras estruturas do processador.
3. **Callbacks com contexto**: Armazenar ponteiros como `usize` em APIs C que usam `void*` para dados de usuário e recuperá-los posteriormente.
4. **Alocadores de memória**: Converter endereços calculados aritmeticamente de volta para ponteiros utilizáveis.
5. **Depuração**: Criar ponteiros para endereços conhecidos ao investigar dumps de memória.

## Considerações de alinhamento

Um requisito fundamental de `@ptrFromInt` é que o endereço fornecido deve satisfazer o alinhamento do tipo de destino. Se o tipo `T` requer alinhamento de 4 bytes, o endereço deve ser múltiplo de 4. Violar essa regra causa undefined behavior em ReleaseFast ou panic em modo safe.

```zig
// Verificar alinhamento antes do cast
fn ptrSeguro(comptime T: type, endereco: usize) ?*T {
    const alinhamento = @alignOf(T);
    if (endereco % alinhamento != 0) return null;
    return @ptrFromInt(endereco);
}
```

## Uso com volatile em MMIO

Registradores de hardware mapeados em memória devem quase sempre ser acessados via ponteiros `volatile`, para evitar que o compilador otimize ou reordene os acessos:

```zig
// Correto para MMIO: sempre usar *volatile
const UART_DR: *volatile u32 = @ptrFromInt(0x4000_4400);

// Ler o registrador sem otimização
const dado = UART_DR.*;

// Escrever no registrador (cada escrita é preservada)
UART_DR.* = 0x41; // 'A'
```

Sem `volatile`, o compilador pode eliminar leituras repetidas ou reordenar escritas — comportamento correto para memória normal, mas catastrófico para I/O de hardware.

## Comparação com equivalente em C

Em C, a conversão de inteiro para ponteiro usa cast explícito:

```c
// C: cast de inteiro para ponteiro
#define UART_BASE 0x40004400UL
volatile unsigned int *uart = (volatile unsigned int *)UART_BASE;
*uart = 0x41;
```

Em Zig, a mesma operação é mais explícita sobre a natureza da conversão:

```zig
// Zig: conversão explícita com tipo inferido pelo contexto
const uart: *volatile u32 = @ptrFromInt(0x4000_4400);
uart.* = 0x41;
```

## Erros comuns

**1. Usar endereço nulo sem verificação:**
```zig
// PERIGOSO: derreferenciar endereço 0 causa segfault
const ptr: *u32 = @ptrFromInt(0);
_ = ptr.*; // undefined behavior / crash

// CORRETO: verificar se o endereço é válido antes de usar
const endereco: usize = obterEndereço();
if (endereco == 0) return error.EnderecoNulo;
const ptr: *u32 = @ptrFromInt(endereco);
```

**2. Esquecer `volatile` em MMIO:**
```zig
// ERRADO: compilador pode otimizar/eliminar leituras
const reg: *u32 = @ptrFromInt(0x4000_0000);

// CORRETO: volatile garante que cada acesso seja emitido
const reg: *volatile u32 = @ptrFromInt(0x4000_0000);
```

**3. Misturar com `@ptrCast` desnecessariamente:** Se você já tem um ponteiro e quer mudar o tipo, use `@ptrCast` diretamente. `@ptrFromInt` é apenas para quando você parte de um inteiro.

## Perguntas Frequentes

**P: Qual é a diferença entre `@ptrFromInt` e `@intFromPtr`?**

R: São operações inversas. `@intFromPtr` converte um ponteiro existente para seu endereço numérico (`*T` → `usize`). `@ptrFromInt` faz o caminho contrário: cria um ponteiro a partir de um endereço numérico (`usize` → `*T`). Juntos, permitem armazenar e recuperar ponteiros em APIs que usam inteiros para contexto (como callbacks C com `void *`).

**P: `@ptrFromInt` pode ser usado em comptime?**

R: Apenas em contextos onde o endereço é conhecido em comptime (raro em código normal). Em comptime, o compilador não tem acesso ao espaço de endereçamento de runtime, então a maioria dos usos de `@ptrFromInt` é exclusivamente runtime.

**P: Como usar `@ptrFromInt` com linker symbols?**

R: Para acessar símbolos do linker (como `__start_data` em scripts de linker), declare-os como `extern` e use `@intFromPtr` para obter o endereço, ou use `@ptrFromInt` com o valor exportado:

```zig
extern const __heap_start: u8;
const heap_inicio: usize = @intFromPtr(&__heap_start);
```

## Builtins relacionados

- [@intFromPtr](/builtins/int-from-ptr/) — Operação inversa: converte ponteiro para inteiro
- [@ptrCast](/builtins/ptr-cast/) — Conversão entre tipos de ponteiro
- [@alignCast](/builtins/align-cast/) — Ajusta alinhamento de ponteiro
- [@volatileCast](/builtins/volatile-cast/) — Remove qualificador volatile

## Tutoriais relacionados

- [Ponteiros em Zig](/tutoriais/ponteiros/)
- [Programação de sistemas](/tutoriais/sistemas/)
- [Desenvolvimento embarcado com Zig](/tutoriais/embarcado/)
