Вводит ли новая позиция точку последовательности? - PullRequest
12 голосов
/ 27 июня 2011

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

new (p++) T();

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

Ответы [ 5 ]

8 голосов
/ 27 июня 2011

Начиная с версии 5.3.4 [expr.new] (цитата из n3242):

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

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

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

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

4 голосов
/ 27 июня 2011

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

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

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

3 голосов
/ 27 июня 2011

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

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

0 голосов
/ 27 июня 2011

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

0 голосов
/ 27 июня 2011

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

  1. сохраняет старое значение во внутренней копии
  2. с шагом в один
  3. возвращает старое значение
  4. удаляет копию старого значения

Итак, p гарантированно увеличивается.

...