Но ведь еще определен оператор приведения указателя к целому числу и назад.
Но вот сравнение чисел после такой конверсии не обязано совпадать со сравнением указателей.
А вроде и не надо. Строгое равенство будет совпадать, т.к. конверсия однозначная. А нестрогое сравнение будет однозначно обладать транзитивностью. Хоть и своей транзитивностью, но для решения практических задач (при работе с коллекциями) этого более чем достаточно.
Это вы забыли про указатели, состоящие из 16-битного дескриптора и 32-битного смещения
Не забыл, засорять эфир не стал.
Но нереальный режим, вроде как, осознанно не поддерживался компиляторами и остался в хрониках джедаев, практиковавших ассемблер, и был быстро замещен честным FLAT, в котором мы и живет до сих пор, расширив его до 64-х бит.
Ещё хуже было чуть раньше, когда дескрипторы ещё не были дескрипторами, а были адресами сегментов, и складывались со смещением чисто арифметически...
Особенно замечательно, что этим все пользовались вопреки стандартам C++. В частности, делая паттерны для реализации больших (более 64K) массивов.
Эхъ, ностальгия... Ладно, если по делу: щас это нам грозит? Если да, то видимо, реализация (компайлер + стандартная библиотека + исполняющая система) должны давать какие-то гарантии на этот счёт, а если не могут - то не носить им гордого звания реализации стандарта.
Щас на всех неэкзотических платформах, включая смартфоны и wifi-коробочки, мы живем в FLAT64 (иногда FLAT32), на практике все указатели и есть прямые адреса в адресном пр-ве процесса и все замечательно.
Также знаковые числа представлены как дополнение до двойки, их переполнение при сложении/вычитании определено и аналогично беззнаковым. А при умножении почти всегда остается остаток по степени двойки и почти везде уже LITTLE-ENDIAN