为什么f(i = -1,i = -1)未定义行为?
我正在阅读有关评估违规的顺序,它们举了一个令人困惑的例子。 1)如果相对于同一标量对象上的另一个副作用,未对标量对象上的副作用进行排序,则该行为未定义。 // snip f(i = -1, i = -1); // undefined behavior 在这种情况下,i是标量对象,这显然意味着 算术类型(3.9.1),枚举类型,指针类型,指向成员类型的指针(3.9.2),std :: nullptr_t和这些类型的cv限定版本(3.9.3)统称为标量类型。 在这种情况下,我看不出该陈述的模棱两可。在我看来,无论是第一个还是第二个参数都首先被求值,结果i都为-1,并且两个参数也都是-1。 有人可以澄清一下吗? 更新 我非常感谢所有讨论。到目前为止,我非常喜欢@harmic的答案,因为尽管乍一看看上去很直截了当,但它暴露了定义此语句的陷阱和复杂性。@ acheong87指出了使用引用时出现的一些问题,但我认为这与该问题的无序副作用方面是正交的。 摘要 既然这个问题引起了很多关注,我将总结要点/答案。首先,请允许我指出一下“为什么”可能具有紧密相关但又微妙的不同含义,即“出于何种原因 ”,“出于何种原因 ”和“出于何种目的 ”。我将按照回答“为什么”的含义中的哪一个分组答案。 是什么原因 这里的主要答案来自Paul Draper,Martin J做出了类似但不太广泛的答案。保罗·德雷珀(Paul Draper)的答案归结为 这是未定义的行为,因为未定义行为是什么。 就解释C ++标准所说的内容而言,答案总体来说是非常好的。它还解决了UB的一些相关情况,例如f(++i, ++i);和f(i=1, i=-1);。在第一种相关情况下,不清楚第一个参数是否应为i+1第二个参数,i+2反之亦然;在第二个中,不清楚i函数调用后应为1还是-1。这两种情况都是UB,因为它们属于以下规则: 如果相对于相同标量对象上的另一个副作用,未对标量对象上的副作用进行排序,则该行为未定义。 因此,f(i=-1, i=-1)UB也是如此,因为它属于同一规则,尽管程序员(IMHO)的意图是明显且明确的。 保罗·德雷珀(Paul Draper)在其结论中也明确指出: 可以定义行为吗?是。定义好了吗?没有。 这带给我们一个问题:“由于什么原因/目的f(i=-1, i=-1)留下未定义的行为?” 由于什么原因/目的 尽管C ++标准中存在一些疏漏(可能是粗心大意),但是许多遗漏是有道理的,并且可以满足特定的目的。尽管我知道目的通常是“使编译器-编写器的工作更轻松”或“更快的代码”,但我主要还是想知道是否有充分理由离开 f(i=-1, i=-1) …