Поделиться через


__sptr, __uptr

Блок, относящийся только к системам Майкрософт

__sptr__uptr Используйте модификатор в 32-разрядном объявлении указателя, чтобы указать, как компилятор преобразует 32-разрядный указатель на 64-разрядный указатель. 32-разрядный указатель преобразуется, например, при присвоении 64-разрядной переменной или при разыменовывании на 64-разрядной платформе.

В документации корпорации Microsoft по поддержке 64-разрядных платформ иногда старший значащий бит 32-разрядного указателя называется знаковым битом. По умолчанию компилятор использует расширение знака для преобразования 32-разрядного указателя в 64-разрядный. При этом для младших значащих 32 битов 64-разрядного указателя устанавливается значение 32-разрядного указателя, а для старших значащих 32 битов устанавливается значение знакового бита 32-разрядного указателя. Такое преобразование дает правильные результаты, если знаковый бит равен 0, но если он равен 1, то результаты получаются неправильные. Например, 32-разрядный адрес 0x7FFFFFFF преобразуется в эквивалентный 64-разрядный адрес 0x000000007FFFFFFF, а 32-разрядный адрес 0x80000000 ошибочно преобразуется в 0xFFFFFFFF80000000.

Модификатор __sptrуказателя со знаком указывает, что преобразование указателя задает наиболее значимые биты 64-разрядного указателя на знак 32-разрядного указателя. Модификатор __uptr(или без знака) указывает, что преобразование присваивает наиболее значимым битам нулевое значение. В следующих объявлениях показаны __sptr и __uptr модификаторы, используемые с двумя неквалифицированными указателями, двумя указателями, соответствующими типу __ptr32 , и параметру функции.

int * __sptr psp;
int * __uptr pup;
int * __ptr32 __sptr psp32;
int * __ptr32 __uptr pup32;
void MyFunction(char * __uptr __ptr32 myValue);

__sptr Используйте модификаторы с __uptr объявлениями указателя. Используйте модификаторы в позиции квалификатора типа указателя, что означает, что модификатор должен следовать звездочку. Модификаторы нельзя использовать с указателями на элементы. Модификаторы не влияют на объявления, не являющиеся объявлениями указателей.

Для совместимости с предыдущими версиями _sptr и _uptr являются синонимами __sptr и __uptr если параметр компилятора /Za (Отключить расширения языка) не указан.

Пример

В следующем примере объявляются 32-разрядные указатели, использующие __sptr и __uptr модификаторы, присваивает каждому 32-разрядному указателю 64-разрядную переменную указателя, а затем отображает шестнадцатеричное значение каждого 64-разрядного указателя. Пример компилировался с помощью собственного 64-разрядного компилятора и выполнялся на 64-разрядной платформе.

// sptr_uptr.cpp
// processor: x64
#include "stdio.h"

int main()
{
    void *        __ptr64 p64;
    void *        __ptr32 p32d; //default signed pointer
    void * __sptr __ptr32 p32s; //explicit signed pointer
    void * __uptr __ptr32 p32u; //explicit unsigned pointer

// Set the 32-bit pointers to a value whose sign bit is 1.
    p32d = reinterpret_cast<void *>(0x87654321);
    p32s = p32d;
    p32u = p32d;

// The printf() function automatically displays leading zeroes with each 32-bit pointer. These are unrelated
// to the __sptr and __uptr modifiers.
    printf("Display each 32-bit pointer (as an unsigned 64-bit pointer):\n");
    printf("p32d:       %p\n", p32d);
    printf("p32s:       %p\n", p32s);
    printf("p32u:       %p\n", p32u);

    printf("\nDisplay the 64-bit pointer created from each 32-bit pointer:\n");
    p64 = p32d;
    printf("p32d: p64 = %p\n", p64);
    p64 = p32s;
    printf("p32s: p64 = %p\n", p64);
    p64 = p32u;
    printf("p32u: p64 = %p\n", p64);
    return 0;
}
Display each 32-bit pointer (as an unsigned 64-bit pointer):
p32d:       0000000087654321
p32s:       0000000087654321
p32u:       0000000087654321

Display the 64-bit pointer created from each 32-bit pointer:
p32d: p64 = FFFFFFFF87654321
p32s: p64 = FFFFFFFF87654321
p32u: p64 = 0000000087654321

Завершение блока, относящегося только к системам Майкрософт

См. также

Модификаторы, используемые в системах Майкрософт