placement-new是否会引入序列点?

时间:2011-06-27 17:56:50

标签: c++ exception constructor side-effects sequence-points

考虑以下代码行:

new (p++) T();

如果构造函数T()抛出异常,p保证已经增加了吗?

5 个答案:

答案 0 :(得分:8)

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

  

11 使用新的放置语法   为...提供额外的参数   分配功能。如果使用,过载   分辨率是在一个函数上执行的   通过组装参数创建的调用   列表由空间量组成   要求(第一个参数)和   新放置部分中的表达式   新表达式(第二个和第二个)   接下来的论点。)

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

  

1 分配函数应该是类成员函数或全局函数; [...]

因此,当从构造函数抛出异常时,已经进行了分配,并且已经完全评估了相关的函数调用表达式。

答案 1 :(得分:4)

是的,保证会增加。

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

因此,在调用函数new之前,所有参数都被完全评估(带有序列点)。

答案 2 :(得分:3)

我不认为该标准直接/明确地回答了这个问题。然而,隐含地,答案是肯定的。

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

答案 3 :(得分:0)

Placement new只是一个名为operator new(size_t, void*)的常规函数​​。它只是返回它的第二个参数。

答案 4 :(得分:-1)

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

  1. 将旧值存储在内部副本中
  2. 增加一个
  3. 返回旧值
  4. 删除旧值的副本
  5. 因此,p保证会增加。