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代码>因为它更容易理解,而且不同的语义(引发异常时没有增量)更适合我的程序逻辑。