auto a = new int[0];
Согласно [basic.compound.3] , значение, хранимое в, aдолжно быть одним из следующих:
- Указатель на объект (типа
int)
- Указатель за концом объекта
- Значение NULL
- Недействительным
Мы можем исключить первую возможность, так как не было построено объектов типа int. Третья возможность исключена, поскольку C ++ требует, чтобы возвращался ненулевой указатель (см. [Basic.stc.dynamic.allocation.2] ). Таким образом, у нас остается две возможности: указатель за концом объекта или неверный указатель.
Я был бы склонен рассматривать aкак указатель "за конец", но у меня нет авторитетной ссылки, чтобы окончательно установить это. (Однако в [basic.stc] есть сильное следствие этого , видя, как вы можете использовать deleteэтот указатель.) Поэтому в этом ответе я рассмотрю обе возможности.
Между инициализацией и удалением копии вы можете читать указатель на a + 1?
Поведение не определено, как предписано [expr.add.4] , независимо от того, какая возможность сверху применима.
Если aуказатель конца-конца, то считается, что он указывает на гипотетический элемент по индексу 0массива без элементов. Добавление целого числа jк aопределяется только тогда 0≤0+j≤n, когда , где nэто размер массива. В нашем случае nэто ноль, поэтому сумма a+jопределяется только тогда, когда jесть 0. В частности, добавление 1не определено.
Если aнедействительно, то мы чисто попадаем в «В противном случае, поведение не определено». (Не удивительно, что определенные случаи охватывают только допустимые значения указателя.)
Кроме того, позволяет ли язык компилятору установить aзначение nullptr?
Нет. Из вышеупомянутого [basic.stc.dynamic.allocation.2] : «Если запрос выполняется успешно, значение, возвращаемое заменяемой функцией распределения, является ненулевым значением указателя» . Существует также сноска, в которой говорится, что C ++ (но не C) требует ненулевого указателя в ответ на нулевой запрос.
aнаверняка (вы, конечно, не можете разыменовать его).