Есть ли разница между uintptr_t и unsigned int, когда unsigned int может содержать любой адрес? - PullRequest
1 голос
/ 08 октября 2019

Описание uintptr_t:

Следующий тип обозначает целочисленный тип без знака со свойством, что любой допустимый указатель на void может быть преобразован в этот тип, а затем преобразован обратно в указатель на void,и результат будет сравниваться равным исходному указателю:

uintptr_t

И так как любой указатель может быть преобразован в указатель void и наоборот:

Указатель на void может быть преобразован в или из указателя на любой тип объекта. Указатель на любой тип объекта может быть преобразован в указатель на void и обратно;результат должен сравниться с исходным указателем.

Любой указатель может быть преобразован в uintptr_t и наоборот, ОК.

Теперь описание целых чисел и указателей:

[Integer -> Pointer]

Целое число может быть преобразовано в любой тип указателя. За исключением случаев, указанных ранее, результат определяется реализацией, может быть неправильно выровнен, может не указывать на объект ссылочного типа и может быть представлением прерывания

[Pointer -> Integer]

Любой тип указателя может быть преобразован в целочисленный тип. За исключением случаев, указанных ранее, результат определяется реализацией. Если результат не может быть представлен в целочисленном типе, поведение не определено. Результат не обязательно должен находиться в диапазоне значений любого целочисленного типа.

ОК. Теперь, поскольку в моей системе ABI (стандарт вызова процедур для архитектуры ARM) и unsigned int, и указатели имеют одинаковый размер и выравнивание, а моя система использует простые 32-битные непрерывные значения, начиная с 0x0 для адресов памяти, кажется, что реализация определяетсяВ моей системе заполнен пробел в преобразовании

Integer -> Pointer и Pointer -> Integer

, и я могу безопасно конвертировать указатели в целые числа без знака, и нет разницы между преобразованием указателяв uintptr_t и преобразование указателя в unsigned int в моей системе (оба приведут к одному и тому же значению). Я прав с моим предположением? или что-то мне не хватает?

1 Ответ

2 голосов
/ 08 октября 2019

Даже учитывая, что unsigned int имеет достаточно битов для представления всех адресов в реализации C, стандарт C не гарантирует, что это означает, что при указателе void * p выражение (void *) (unsigned) p == p оценивается как true. Поскольку преобразование из void * в целое число определяется реализацией, оно может сделать больше, чем просто воспроизвести адрес как значение unsigned. Он может содержать некоторые биты, описывающие происхождение адреса или контрольную сумму, и unsigned может быть недостаточно, чтобы содержать необходимую информацию для восстановления исходного значения.

Большинство реализаций, вероятно, просто преобразуют адрес вочевидный способ - интерпретировать биты адреса виртуальной памяти как значение unsigned, и никаких проблем не возникнет. Однако это особенность реализации;это не требование стандарта C.

...