Я знаю, что некоторые ответы здесь говорят, что вы не можете сравнивать указатели, если они не указывают на одну и ту же структуру, но это красная сельдь, и я попытаюсь объяснить почему.Один из ваших указателей указывает на начало вашего массива, другой на конец, поэтому они указывают на одну и ту же структуру.Специалист по языку может сказать, что если ваш третий указатель указывает за пределы объекта, сравнение не определено, поэтому x >= array.start
может быть true
для всех x
.Но это не проблема, так как в момент сравнения C ++ не может знать, не встроен ли массив в еще большую структуру.Кроме того, если ваше адресное пространство является линейным, как это должно быть в наши дни, сравнение указателей будет реализовано как (не) целочисленное сравнение со знаком, поскольку любая другая реализация будет медленнее.Даже во времена сегментов и смещений (дальнее) сравнение указателей было реализовано путем сначала нормализации указателя, а затем сравнения их как целых чисел.
То, что все это сводится к тому, что если ваш компилятор в порядке,Сравнение указателей, не беспокоясь о знаках, должно сработать, если все, что вас волнует, это то, что указатель указывает в массиве, поскольку компилятор должен делать указатели со знаком или без знака в зависимости от того, какую из двух границ объект C ++ может охватывать.
В этом вопросе разные платформы ведут себя по-разному, поэтому C ++ должен оставить это на усмотрение платформы.Есть даже платформы, в которых оба адреса около 0 и 80..00h не сопоставимы или уже заняты при запуске процесса.В этом случае это не имеет значения, если вы последовательны в этом.
Иногда это может вызвать проблемы совместимости.Как пример, в Win32 указатели не подписаны.Раньше было так, что из 4 ГБ адресного пространства только нижняя половина (точнее, 10000h ... 7FFFFFFFh, из-за раздела назначения указателя NULL) была доступна для приложений;высокие адреса были доступны только ядру.Из-за этого некоторые люди помещали адреса в подписанные переменные, и их программы продолжали работать, поскольку старший бит всегда был равен 0. Но затем появился переключатель /3GB
, который сделал почти 3 ГБ доступными для приложений (точнее, 10000h ... BFFFFFFFh)и приложение будет аварийно завершать работу или работать некорректно.
Вы явно заявляете, что ваша программа будет работать только в Windows, в которой используются указатели без знака.Однако, возможно, в будущем вы передумаете, и использование intptr_t
или uintptr_t
плохо для мобильности.Мне также интересно, стоит ли вам вообще это делать ... если вы индексируете в массив, было бы безопаснее вместо этого сравнивать индексы.Предположим, например, что у вас есть массив 1 ГБ с 1500000h ... 41500000h, состоящий из 16,384 элементов по 64 КБ каждый.Предположим, вы случайно посмотрели индекс 80 000 - явно вне диапазона.Вычисление указателя даст 39D00000h, поэтому ваша проверка указателя позволит это сделать, даже если это не так.