C++ 新放置是否引入了序列点?

C++ 新放置是否引入了序列点?,c++,exception,constructor,side-effects,sequence-points,C++,Exception,Constructor,Side Effects,Sequence Points,考虑以下代码行: new (p++) T(); 如果构造函数T()抛出异常,p是否保证已递增?递增运算符执行以下操作: 将旧值存储在内部副本中 递增一 返回旧值 删除旧值的副本 因此,p保证递增。Placement new只是一个常规函数,名为操作符new(size\u t,void*)。它只返回第二个参数。是,它保证递增 运算符只是函数/方法调用的语法糖。 我不相信new在操作符上面有任何特殊的含义,所以它应该是相同的 因此,在调用函数new之前,所有参数都经过了充分评估(带有序列点)。我认

考虑以下代码行:

new (p++) T();

如果构造函数
T()
抛出异常,
p
是否保证已递增?

递增运算符执行以下操作:

  • 将旧值存储在内部副本中
  • 递增一
  • 返回旧值
  • 删除旧值的副本

  • 因此,
    p
    保证递增。

    Placement new只是一个常规函数,名为
    操作符new(size\u t,void*)
    。它只返回第二个参数。

    是,它保证递增

    运算符只是函数/方法调用的语法糖。
    我不相信new在操作符上面有任何特殊的含义,所以它应该是相同的


    因此,在调用函数
    new
    之前,所有参数都经过了充分评估(带有序列点)。

    我认为标准没有直接/明确地回答这个问题。然而,答案是肯定的

    特别是,new的placement语法只是一种指定将传递给函数的额外参数的方法。与任何其他函数调用一样,在计算函数的所有参数(按未指定的顺序)和执行函数中的任何代码之间存在一个序列点。我相信这意味着您的
    p++
    将在任何其他情况发生之前进行评估并应用所有副作用。

    来自5.3.4[expr.new](引用自n3242):

    11新的放置语法用于 向 分配功能。如果使用,过载 解析是对函数执行的 通过组合参数创建的调用 由空间量组成的列表 请求(第一个参数)和 新放置零件中的表达式 新表达式(第二个和 随后的论点)

    因此,在一个新的表达式中,分配函数是从函数调用中使用的(这是有意义的)。所有分配函数都是3.7.4.1[basic.stc.dynamic.allocation]中的函数,包括实现提供的函数:

    1分配函数应为类成员函数或全局函数;[……]


    因此,当构造函数抛出异常时,分配已经发生,关联的函数调用表达式已经完全计算。

    不要这么肯定。例如,看这个问题:增量在下一个序列点之前不保证可见,这就是我的问题所在。好的@FredOverflow,错过了答案中的主题,sry@Fred Larson,你是对的,我应该告诉你:这只是标准定义。如果编译器不是这样做的,那是另外一回事。你把新的位置和新的
    操作符混为一谈了。确切地说,placement new是一种调用运算符new的重载形式的语法,但普通人也只是称这些形式为placement new。placement new和运算符new是正交概念。非常正交的概念。如果您使用placement new,则不会调用运算符new。这是一个很好的问题,但我希望您永远不会编写这样的代码:-)@sel:事实上,我将其替换为
    new(p)T()++p因为它更容易理解,而且不同的语义(引发异常时没有增量)更适合我的程序逻辑。