增值变量是否可以在平局通话中重用?

时间:2019-07-11 15:59:43

标签: c++ increment undefined-behavior function-call tie

因此,我知道已递增使用的变量的重用为undefined behavior in a function call。我的理解是,这在构造函数中不是问题。我的问题是关于tie,它们之间的距离很奇怪。

鉴于:pair<int, int> func()我可以这样做:

tie(*it++, *it) = func();

还是那不确定的行为?

1 个答案:

答案 0 :(得分:3)

从C ++ 17开始,此代码具有未指定的行为。有两种可能的结果:

  • 第一个参数是解引用原始迭代器的结果,第二个参数是解引用增量迭代器的结果;或

  • 第一个参数和第二个参数都是取消引用原始迭代器的结果。

[expr.call]/8

  

[...]参数的初始化,包括每个关联的参数   值计算和副作用,不确定地与   尊重其他任何参数。 [...]

因此tie的第二个参数可能是取消引用增量迭代器的结果,也可能是原始迭代器的解引用。


在C ++ 17之前,情况有点复杂:

  • 如果++*都调用一个函数(例如,当it的类型是复杂的类时),则行为是未指定,类似于自C ++ 17以来的情况;

  • 否则,行为是未定义

每个N4140(C ++ 14草案)[expr.call]/8

  

[注意: 后缀表达式和   争论彼此之间都是无序的。   参数求值的效果先于函数   输入(请参阅[intro.execution])。 — 尾注]

因此,该代码是未定义的行为,因为一个参数的求值未与另一个参数进行排序。这两个参数的求值可能会重叠,从而导致数据争用。除非另有说明...

每个N4140 [intro.execution]/15

  

在调用函数(无论函数是否为内联)时,每个   与任何参数相关的值计算和副作用   表达式,或者用后缀表达式指定被调用   函数,在执行每个表达式或   被调用函数主体中的语句。 [注意:值   与不同论点相关的计算和副作用   表达式是无序列的。 — 尾注] 每次评估   在调用函数(包括其他函数调用)中   否则在执行之前或之后专门排序   调用函数的主体相对于    9 几个   即使没有,C ++中的上下文也会导致函数调用的求值   相应的函数调用语法出现在翻译单元中。   [   示例:对新表达式的求值调用一个或多个分配和构造函数;参见[expr.new]。为了另一个   例如,调用转换函数([class.conv.fct])可以   在没有函数调用语法出现的上下文中出现。 -   最终示例] 被调用函数的执行顺序约束(如上所述)是该函数的功能   按求值方式调用,无论调用的表达式的语法是什么   该功能可能是。

     

9)   换句话说,函数执行不会与每个函数交织   其他。

因此,如果运算符实际上是函数调用,则行为类似地未指定。