考虑以下表达式(声明用于公开):
int n = 42;
--n &= 0x01;这是否违反了排序规则?
在我看来,预增量需要作为左操作数“值计算”的一部分。如果是这样的话,这里就没有UB了,因为C++11 (而且,自C++17以来,值计算和副作用都是相对于赋值排序的)。
如果这是一个后增量,那么n的修改将仅仅是一个副作用,我们将不会有良好的测序(直到C++17)。
发布于 2019-10-22 11:06:31
我想你是对的,标准是这样说的:
8.5.18分配和复合赋值运算符
它们都需要一个可修改的lvalue作为它们的左操作数;它们的结果是一个指向左操作数的lvalue。..。在所有情况下,分配都是在计算右和左操作数的值之后,以及在分配表达式的值计算之前进行的。
因此,从上面看,赋值似乎是值的表达,赋值的左和右都是在赋值之前计算的。
从关于增量前的标准:
8.5.2.2增长和减少
结果是更新的操作数;它是一个lvalue,如果操作数是位字段,则是位字段。表达式++x等效于x+=1。
这意味着,即使在C++17之前,其副作用也是在值计算之前进行排序的。
发布于 2019-10-22 11:27:04
据我所知,C++11中的措辞没有提到与更新相关的增量前和预递减的“值计算”:
expr.pre.incr 1前缀++的操作数是通过添加1来修改的,如果它是bool,则设置为true (不推荐这种用法)。操作数应为可修改的lvalue。操作数的类型应该是算术类型或指向完全定义的对象类型的指针。结果是更新的操作数;它是一个lvalue,如果操作数是位字段,则是位字段。如果x不是bool类型,则表达式++x等效于x+=1。
以上段落中没有什么是我认为修改必须放在第一位的。在下一个序列点将更新的值写入对象之前,实现可以很好地计算更新的值(并使用它)。
在这种情况下,我们将有一个副作用,这是不确定的顺序与另一个修改。所以我要说的是,既然标准没有规定是否有副作用,也没有规定这种潜在的副作用是如何排序的,所以整件事都没有被省略的定义。
使用C++17,我们当然得到了明确的测序,不管有没有这种潜在的副作用。
https://stackoverflow.com/questions/58502699
复制相似问题