Рассмотрим следующую строку кода:
new (p++) T();
Если конструктор T()
выдает исключение, гарантируется, что p
уже был увеличен?
Рассмотрим следующую строку кода:
new (p++) T();
Если конструктор T()
выдает исключение, гарантируется, что p
уже был увеличен?
Из 5.3.4 [expr.new] (цитирование из n3242):
11 Синтаксис нового места размещения используется для предоставить дополнительные аргументы функция распределения. Если используется, перегрузка разрешение выполняется по функции вызов, созданный путем сборки аргумента список, состоящий из объема пространства (первый аргумент) и выражения в части нового размещения нового выражения (второе и последующие аргументы).
Итак, в новом выражении функция выделения используется из вызова функции (что имеет смысл). Все функции распределения - это функции, в том числе предоставляемые реализацией, из 3.7.4.1 [basic.stc.dynamic.allocation]:
1 Функция распределения должна быть функцией-членом класса или глобальной функцией; [...]
Итак, к тому времени, когда исключение выбрано из конструктора, распределение было выполнено, и соответствующее выражение вызова функции было полностью оценено.
Да гарантируется, что он будет увеличен.
Операторы - это просто синтаксический сахар для вызовов функций/методов.
Я не верю, что новый имеет значение выше оператора, поэтому он должен быть тем же.
Таким образом, все параметры полностью оцениваются (с точкой последовательности) до вызова функции new
.
Я не думаю, что стандарт отвечает на этот вопрос напрямую/явно. Неявно, однако, ответ да.
В частности, синтаксис размещения для нового - это просто способ указания дополнительных параметров, которые будут переданы функции. Как и любой другой вызов функции, существует точка последовательности между оценкой всех параметров функции (в неуказанном порядке) и выполнением любого кода в функции. Я считаю, что это должно означать, что ваш p++
будет оценен и все побочные эффекты будут применены до того, как произойдет что-либо еще.
Размещение new - это просто регулярная функция с именем operator new(size_t, void*)
. Он просто возвращает свой второй аргумент.
Оператор приращения выполняет следующее:
Таким образом, p
гарантированно увеличивается.