auto a = new int[0];
Согласно [basi c .compound.3] значение, хранимое в a
, должно быть одним из следующих:
- Указатель на объект (типа
int
) - Указатель за концом объекта
- Нуль
- Недопустимый
Мы можем исключить первую возможность, поскольку не было построено объектов типа int
. Третья возможность исключена, поскольку C ++ требует, чтобы возвращался ненулевой указатель (см. [basi c .st c .dynami c .allocation.2] ). Таким образом, у нас остается две возможности: указатель за концом объекта или недопустимый указатель.
Я был бы склонен рассматривать a
как указатель конца конца, но я не имеют авторитетную ссылку на окончательно установить sh, что. (Тем не менее, это имеет сильное значение в [basi c .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
?
Нет. Из вышеупомянутого [basi c .st c .dynami c .allocation.2] : "Если запрос завершается успешно, значение, возвращаемое заменяемой функцией распределения, равно ненулевое значение указателя ". Существует также сноска , в которой говорится, что C ++ (но не C) требует ненулевого указателя в ответ на нулевой запрос.