Какие значения указателя четко определены для вычисления? - PullRequest
3 голосов
/ 19 апреля 2020

У меня сложилось впечатление, что, хотя разыменование указателей, которые не указывают на действительный объект, является UB, просто вычисление таких указателей в порядке.

Однако, если я правильно понимаю expr.add [4] , это не так.

Итак, какие из этих вычислений указателей четко определены?

int a = 42;
int *p = &a;
p;           // valid, and obviously ok
p++;         // invalid, but ok, because one past the end of 'array' containing 1 element?
p++;         // UB ?

Как насчет этого дела?

int *p = nullptr;
p;                // invalid, and obviously ok (considered one past the end?)
p++;              // one past the end? or UB?

1 Ответ

3 голосов
/ 19 апреля 2020

В вашем первом примере первый p++ четко определен, поскольку не массив считается массивом одной длины.

Вот соответствующая цитата ( basi c .compound / 3.4 ):

Для целей арифметики указателей c ([expr.add] ) и сравнения ([expr.rel], [expr.eq]) указатель за концом последнего элемента массива x из n элементов считается эквивалентным указателю на гипотетический элемент массива n из x и объект типа T, который не является элементом массива, считается принадлежащим массиву с одним элементом типа T .

После p++, p он будет указать последний (и единственный) элемент (гипотетического) массива, который четко определен. Это не «неверно, но нормально», так как указатели, указывающие на конец объекта, не являются недействительными указателями, basi c .compound / 3.2 :

Every значение типа указателя может быть одним из следующих:

  • [...]

  • a указатель за концом объекта

  • [...]

  • недопустимое значение указателя.

Второй p++ первого примера - UB, потому что результат будет указывать после гипотетического (& a) [1] элемента, который не определен.

Во втором примере p++ равен UB, потому что только 0 может быть добавлено к nullptr ( expr.add / 4.1 ):

  • Если P оценивается как значение нулевого указателя и значение J равно 0 , результатом является значение нулевого указателя.

  • [...]

  • В противном случае поведение не определено .

...