首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >编写新值是增量前表达式的“值计算”的一部分,还是“副作用”?

编写新值是增量前表达式的“值计算”的一部分,还是“副作用”?
EN

Stack Overflow用户
提问于 2019-10-22 10:57:33
回答 2查看 153关注 0票数 5

考虑以下表达式(声明用于公开):

代码语言:javascript
复制
int n = 42;
--n &= 0x01;

这是否违反了排序规则?

在我看来,预增量需要作为左操作数“值计算”的一部分。如果是这样的话,这里就没有UB了,因为C++11 (而且,自C++17以来,值计算和副作用都是相对于赋值排序的)。

如果这是一个后增量,那么n的修改将仅仅是一个副作用,我们将不会有良好的测序(直到C++17)。

EN

回答 2

Stack Overflow用户

发布于 2019-10-22 11:06:31

我想你是对的,标准是这样说的:

8.5.18分配和复合赋值运算符

它们都需要一个可修改的lvalue作为它们的左操作数;它们的结果是一个指向左操作数的lvalue。..。在所有情况下,分配都是在计算右和左操作数的值之后,以及在分配表达式的值计算之前进行的。

因此,从上面看,赋值似乎是值的表达,赋值的左和右都是在赋值之前计算的。

从关于增量前的标准:

8.5.2.2增长和减少

结果是更新的操作数;它是一个lvalue,如果操作数是位字段,则是位字段。表达式++x等效于x+=1。

这意味着,即使在C++17之前,其副作用也是在值计算之前进行排序的。

票数 3
EN

Stack Overflow用户

发布于 2019-10-22 11:27:04

据我所知,C++11中的措辞没有提到与更新相关的增量前和预递减的“值计算”:

expr.pre.incr 1前缀++的操作数是通过添加1来修改的,如果它是bool,则设置为true (不推荐这种用法)。操作数应为可修改的lvalue。操作数的类型应该是算术类型或指向完全定义的对象类型的指针。结果是更新的操作数;它是一个lvalue,如果操作数是位字段,则是位字段。如果x不是bool类型,则表达式++x等效于x+=1。

以上段落中没有什么是我认为修改必须放在第一位的。在下一个序列点将更新的值写入对象之前,实现可以很好地计算更新的值(并使用它)。

在这种情况下,我们将有一个副作用,这是不确定的顺序与另一个修改。所以我要说的是,既然标准没有规定是否有副作用,也没有规定这种潜在的副作用是如何排序的,所以整件事都没有被省略的定义。

使用C++17,我们当然得到了明确的测序,不管有没有这种潜在的副作用。

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

https://stackoverflow.com/questions/58502699

复制
相关文章

相似问题

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