Подтвердить что ты не робот

Включает ли размещение-новое значение точки последовательности?

Рассмотрим следующую строку кода:

new (p++) T();

Если конструктор T() выдает исключение, гарантируется, что p уже был увеличен?

4b9b3361

Ответ 1

Из 5.3.4 [expr.new] (цитирование из n3242):

11 Синтаксис нового места размещения используется для предоставить дополнительные аргументы функция распределения. Если используется, перегрузка разрешение выполняется по функции вызов, созданный путем сборки аргумента список, состоящий из объема пространства (первый аргумент) и выражения в части нового размещения нового выражения (второе и последующие аргументы).

Итак, в новом выражении функция выделения используется из вызова функции (что имеет смысл). Все функции распределения - это функции, в том числе предоставляемые реализацией, из 3.7.4.1 [basic.stc.dynamic.allocation]:

1 Функция распределения должна быть функцией-членом класса или глобальной функцией; [...]

Итак, к тому времени, когда исключение выбрано из конструктора, распределение было выполнено, и соответствующее выражение вызова функции было полностью оценено.

Ответ 2

Да гарантируется, что он будет увеличен.

Операторы - это просто синтаксический сахар для вызовов функций/методов.
Я не верю, что новый имеет значение выше оператора, поэтому он должен быть тем же.

Таким образом, все параметры полностью оцениваются (с точкой последовательности) до вызова функции new.

Ответ 3

Я не думаю, что стандарт отвечает на этот вопрос напрямую/явно. Неявно, однако, ответ да.

В частности, синтаксис размещения для нового - это просто способ указания дополнительных параметров, которые будут переданы функции. Как и любой другой вызов функции, существует точка последовательности между оценкой всех параметров функции (в неуказанном порядке) и выполнением любого кода в функции. Я считаю, что это должно означать, что ваш p++ будет оценен и все побочные эффекты будут применены до того, как произойдет что-либо еще.

Ответ 4

Размещение new - это просто регулярная функция с именем operator new(size_t, void*). Он просто возвращает свой второй аргумент.

Ответ 5

Оператор приращения выполняет следующее:

  • хранит старое значение во внутренней копии
  • увеличивается на один
  • возвращает старое значение
  • удаляет копию старого значения

Таким образом, p гарантированно увеличивается.