Для указателя p, может ли p <p + 1 быть ложным в крайнем случае?

Возможно ли для переменной указателя p, что p < (p + 1) является ложным? Пожалуйста, объясните свой ответ. Если да, при каких обстоятельствах это может случиться?

Мне было интересно, может ли p + 1 переполняться и быть равно 0.

Например. На 64-битном ПК с GCC-4.8 для программы на языке C:

int main(void) {
   void *p=(void *)0xFFFFFFFFFFFFFFFF;

   printf("p      :%p\n", p);
   printf("p+1    :%p\n", p+1);
   printf("Result :%d\n", p<p+1);
}

Он возвращает:

p      : 0xffffffffffffffff
p+1    : (nil)
Result : 0

Поэтому я считаю, что это возможно для этого случая. Для недопустимого местоположения указателя это может произойти. Это единственное решение, о котором я могу думать. Есть ли другие?

Примечание: Никаких предположений не делается. Рассмотрим любой компилятор/платформу/архитектуру/ОС, где есть вероятность, что это может произойти или нет.

Ответ 1

Возможно ли для переменной указателя p, что p<(p+1) является ложным?

Если p указывает на допустимый объект (т.е. созданный в соответствии с объектной моделью С++) правильного типа, то нет. p+1 будет указывать на ячейку памяти после этого объекта и всегда будет сравнивать больше, чем p.

В противном случае поведение как арифметики, так и сравнения undefined, поэтому результат может быть истинным, ложным или суффиксом желтого.

Если да, при каких обстоятельствах это может произойти?

Он может или не может произойти с

p = reinterpret_cast<char*>(numeric_limits<uintptr_t>::max);

Если арифметика указателя работает как беззнаковая целочисленная арифметика, это может вызвать числовое переполнение, так что p+1 имеет значение 0 и сравнивает менее p. Или это может сделать что-то еще.

Ответ 2

Что делать, если я программирую DOS, и у меня есть дальний указатель (один состоит из сегмента и смещения), и это указывая на последний адрес в сегменте, и я добавляю его к нему, а указатель обходит вокруг? Похоже, когда вы их сравниваете, вы нормализуете указатели, поэтому второй указатель p+1 будет меньше p.

Это удар в темноте, хотя у меня нет компилятора DOS C, который можно протестировать.

Ответ 3

Это может произойти с недопустимым указателем.

Но если указатель указывает на допустимую ячейку памяти, во многих операционных системах (например, на Linux), это практически никогда не происходит (по крайней мере, если sizeof(*p) не слишком большой), поскольку на практике первая и последняя страницы адресное пространство никогда не отображается (но вы можете заставить отображение с mmap и MAP_FIXED).

Для автономных реализаций (т.е. внутри ядра или на каком-то микроконтроллере) все по-другому, и конкретная реализация (возможно, может быть undefined поведение или неуказанное поведение).

Ответ 4

Очень просто: Это не может произойти, если не существует поведения undefined. Это может произойти очень легко в присутствии поведения undefined. Для получения дополнительной информации прочитайте копию Стандарта C или Стандарта С++.

В результате соответствующему компилятору разрешено не оценивать < оператора, и вместо этого использовать 1 или true. То же самое верно для арифметики со знаками целых чисел (но не для целых без знака, где вполне допустимый код имеет x > x + 1).

В вашем примере кода нет даже C или С++, поэтому вы, похоже, использовали компилятор в режиме, где он не является стандартным компилятором C или С++.