我正在阅读有关评估违规的顺序,他们给出了一个令我困惑的例子.
1)如果标量对象的副作用相对于同一标量对象的另一个副作用未按顺序排列,则行为未定义.
Run Code Online (Sandbox Code Playgroud)// 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,因为它属于同一规则,尽管程序员的意图是(恕我直言)显而易见且毫不含糊.
Paul Draper在他的结论中也明确表示
可以定义行为吗?是.它被定义了吗?没有.
这让我们想到"为什么原因/目的是 …