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точно (ви, звичайно, не можете її знехтувати).