Для указателя 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 или С++.
Ответ 5
В соответствии с сравнениями указателей в C. Являются ли они подписанными или неподписанными? в переполнении стека:
Вы не можете юридически сравнивать произвольные указатели в C/С++. Результат такого сравнения не определен.