Является ли переинтерпретация приведения целого числа к указателю биективным, если целое число того же размера, что и указатель? - PullRequest
0 голосов
/ 12 октября 2018

Учитывая целочисленный тип IntT, такой что sizeof(IntT) == sizeof(void*), и переменную указанного типа i, гарантируется ли, что reinterpret_cast<IntT>(reinterpret_cast<void*>(i)) == i?Это похоже на этот вопрос , но этот вопрос рассматривал любое целое число произвольного размера, поэтому ответом было прямое нет.Ограничение его целыми числами точно такого же размера, что и указатель, делает его более интересным.

Мне кажется, что ответом должно быть «да», потому что спецификация утверждает, что существует сопоставление с любым целым числомдостаточно большой, чтобы содержать значение указателя.Если переменные имеют одинаковый размер, то это отображение должно быть биективным.Если это биективно, то это также означает, что преобразование из int в void* также должно быть биективным.

Но есть ли дыра в этой логике?Есть ли в спецификации слово покачивания, которое я не учел?

1 Ответ

0 голосов
/ 12 октября 2018

Я не думаю, что это гарантировано.Стандарт гарантирует, что указатель, преобразованный в достаточно большое целое число и обратно, будет иметь свое первоначальное значение.Из этого следует, что существует отображение от указателей на подмножество соответственно больших целых чисел и обратно.Это не означает, что для каждого достаточно большого целочисленного значения существует соответствующее значение указателя…

Как указывает DavisHerring в комментариях ниже, это означает, что отображение является инъективным, но не имеетбыть сюръективным и, следовательно, биективным.Я полагаю, что стандарт подразумевает в математических терминах, что между указателями и целыми числами существует уникальная слева и общая сумма слева, а не биективная функция.

Просто представьте себе странную архитектуру, в которой по какой-то причинекаждый третий бит адреса должен быть нулевым.Или немного более разумная архитектура, которая использует только младшие 42 бита 64-битного значения для хранения адреса.Независимо от того, какой бы смысл это имело, компилятор мог бы предположить, что целочисленное значение, приводимое к указателю, должно следовать шаблону действительного адреса и, например, маскировать каждый третий бит или использовать только младший шесть байт.соответственно ...

...