Compartilhar via


__ptr32, __ptr64

Específico da Microsoft

Use __ptr32 para representar um ponteiro nativo em um sistema de 32 bits. Use __ptr64 para representar um ponteiro nativo em um sistema de 64 bits.

Os __ptr32 modificadores e os __ptr64 modificadores são extensões específicas da Microsoft para cenários de interoperabilidade. Para código padrão de 32 bits (x86) ou x64 padrão, use ponteiros nativos.

O exemplo a seguir mostra como declarar cada um desses tipos de ponteiro:

int * __ptr32 p32;
int * __ptr64 p64;

Em um sistema de 32 bits, um ponteiro declarado com __ptr64 é tratado como um ponteiro de 32 bits e trunca os 32 bits superiores de qualquer endereço de 64 bits atribuído a ele. Em um sistema de 64 bits, um ponteiro declarado com __ptr32 é tratado como um ponteiro de 32 bits e trunca os 32 bits superiores de qualquer endereço de 64 bits atribuído a ele. Esse truncamento pode levar a um ponteiro inválido se o endereço de 64 bits estiver acima de 4 GB.

Observação

Você não pode usar __ptr32 ou __ptr64 ao compilar com /clr:pure. Caso contrário, o compilador gerará o erro C2472. As opções do compilador /clr:pure e /clr:safe são preteridas no Microsoft Visual Studio 2015 e sem suporte no Microsoft Visual Studio 2017.

Para compatibilidade com versões anteriores, _ptr32 e _ptr64 são sinônimos para __ptr32 e __ptr64 a menos que você especifique a opção do compilador /Za (Desabilitar extensões de linguagem).

Exemplo

O exemplo a seguir mostra como declarar e alocar os ponteiros com as palavras-chave __ptr32 e __ptr64.

Esse código funciona no x86, mas pode falhar no x64.

  • Ele funciona quando compilado para 32 bits porque __ptr64 os ponteiros são tratados como ponteiros de 32 bits no x86. Em x86 (32 bits), malloc retorna um endereço de 32 bits que se encaixa em p64.
  • Ele pode falhar quando compilado para 64 bits porque, em x64, malloc retorna um ponteiro de 64 bits truncado para 32 bits por esta linha: p32 = (int* __ptr32)malloc(4);. Truncar um endereço de 64 bits em um endereço de 32 bits pode resultar em um ponteiro inválido se a alocação ocorresse acima de 4 GB. Nesse caso, *p32 = 32 pode tentar acessar um endereço truncado que não faz parte do espaço de endereço do processo, causando uma violação de acesso. Mesmo que funcione uma vez, ele poderá falhar mais tarde se o alocador de memória retornar um endereço mais alto.
#include <cstdlib>
#include <iostream>

int main()
{
    using namespace std;

    int* __ptr32 p32;
    int* __ptr64 p64;

    p64 = (int* __ptr64)malloc(4);
    *p64 = 64; // Works on x86 and x64
    cout << *p64 << endl; 
    
    p32 = (int* __ptr32)malloc(4);
    *p32 = 32; // Works on x86. Possible exception on x64
    cout << *p32 << endl;
}
64
32

Fim da seção específica da Microsoft

Confira também

Tipos internos