auto a = new int[0];
Відповідно до [basic.compound.3] , значення, яке зберігається в, a
повинно бути одним із таких:
- Вказівник на об’єкт (типу
int
)
- Вказівник повз кінець об’єкта
- Нуль
- Недійсний
Ми можемо виключити першу можливість, оскільки не було 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
точно (ви, звичайно, не можете її знехтувати).