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
наверняка (вы, конечно, не можете разыменовать его).