首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >int a= ++i + ++i是未定义的行为吗?

int a= ++i + ++i是未定义的行为吗?
EN

Stack Overflow用户
提问于 2020-04-17 04:53:10
回答 1查看 291关注 0票数 3

考虑以下代码:

代码语言:javascript
复制
int main(){
  int i = 0;
  int a = ++i + ++i;
}

我找不到任何信息表明+的操作数是未排序的。因此,根据该标准,二进制+的操作数序列是不确定的。

[介绍,执行]/15

对于任何两个评估A和B,如果A是在B之前排序的(或者,相等地,B是在A之后排序的),则A的执行应先于B的执行。如果在B之前没有对A进行排序,而B在A之前没有排序,则A和B是不被排序的。 注意:未排序的评估的执行可能会重叠。当A或B在A之前被排序时,A和B都是不确定排序的,但没有指定哪一个是不确定的。 注意:不确定的排序评估不能重叠,但可以先执行。 - 尾注 

引用意味着A的评估可以发生在B之前,B的评估可以发生在A之前,而未排序的评价的执行可以重叠,而不确定的顺序评价不能重叠,这是不同的。

我们知道,由于前缀i的存在,在计算i值之前总是会对++进行修改。

然后根据规则:

表达式(或子表达式)的计算通常包括值计算()(包括确定用于极值计算的对象的标识,以及获取以前分配给对象用于prvalue评估的值)和副作用的启动。 如果内存位置上的副作用相对于在同一内存位置上的另一个副作用或使用同一内存位置中任何对象的值进行的值计算,并且它们可能不是并发的,则行为是未定义的。

因此,无论A的评估是在B之前,还是在相反的情况下,++i + ++i;都没有相应的数值计算或副作用的副作用。由于不确定的顺序评估不能重叠,所以两个评估中的一个必须在另一个之前完全执行。评价既包括价值计算,也包括副作用。因此,i的一个增量是在另一个增量之前计算的。

但是,未排序的评估遵循不同的规则,因此,如果二进制+的操作数的计算是未排序的,而不是不确定的排序,那么混乱就会得到解决。如果我在上面分析的标准中遗漏了什么,请纠正我。

更新

我发现下面这句话似乎表明这些评价是没有顺序的:

除注意事项外,对单个运算符的操作数和单个表达式的子表达式的计算为unsequenced.。

然而,我不知道如何正确理解这个句子。我想出两种解释:

对于运算符A,A的操作数的计算是彼此不排序的;对于表达式B,B的子表达式的计算是彼此不排序的。

将单个运算符的操作数计算为A。将单个表达式的子表达式计算为B。A不按B排序。

哪种解释是正确的?

EN

回答 1

Stack Overflow用户

发布于 2020-04-20 03:11:29

让我给出一个答案,使问题的答案更加清晰。首先,考虑以下句子

除注意到的情况外,对单个运算符的操作数和单个表达式的子表达式的评估是不按顺序进行的。

这句话可以分两句

1.除注意到的情况外,对个别运营者操作数的评价是不分顺序的。 2.除注意到的情况外,对个别表达式的子表达式的评价是不分顺序的。

那么,1节是什么意思呢?它意味着集合X由运算符的这些操作数组成,集合X的每个元素彼此不排序,它们是unsequenced.The语句2类似于句子1,它只是使集合X由表达式的这些子表达式组成。

二进制运算符+的那些语句用expr.additive描述,这与该节中的操作数序列无关,因此,在operator.Hence上执行的规则1,正如标准所说的,不序列可以重叠,这意味着什么?这意味着“每个评估的部分甚至可以交织在一起”(@Ben在评论中说).So,对于++i + ++i来说,这是典型的情况:

如果内存位置上的副作用相对于在同一内存位置上的另一个副作用或使用同一内存位置中任何对象的值进行的值计算,并且它们不具有潜在的并发性,则该行为是未定义的。

因此,int a = ++i + ++i是未定义的行为,这个问题的关键是理解以下句子:

除注意到的情况外,对单个运算符的操作数和单个表达式的子表达式的评估是不按顺序进行的。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61264384

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档