涉及逻辑AND(&&)的复杂表达式

Raj*_*bey 9 c c++ sequence-points

void main(void)
{
  int x,y,z;
  x=y=z=1;

  z = x && y && ++z;//is this fine?
}
Run Code Online (Sandbox Code Playgroud)

我最近开始阅读关于序列点的东西,但我无法弄清楚上面的代码示例是否正常.我知道&&运算符引入了一个序列点,所以我不太确定表达式z = x && y && ++ z的行为.有人请告诉我正确的答案.

Chu*_*dad 6

在C++ 03中.

void main(void) 
{ 
  int x,y,z; 
  x=y=z=1;                                  // Seq1 at ;

  z = x && y && ++z;//is this fine?         // Seq2 at ;
} 
Run Code Online (Sandbox Code Playgroud)

注意:请注意,运算符&&上有序列点,但是在这个例子中它们不相关.

精细!.一般来说,可能是或可能不是.取决于x和y的值.在你的具体情况下,它并不好.此代码有可能产生一种称为未定义行为的东西.

如果评估z ++(如您的示例中因为x和y为1),则标量变量'z'在两个序列点Seq1和Seq2之间的表达式中被多次修改(见下文).值得注意的是,赋值运算符不会引入任何序列点.

$ 5/4-"除非另有说明,否则单个运算符的操作数和各个表达式的子表达式的评估顺序以及副作用发生的顺序是未指定的.5)在前一个和下一个序列点之间,标量对象应为通过对表达式的求值,最多只修改一次存储值.此外,只能访问先前值以确定要存储的值.对于每个允许的子表达式的排序,应满足本段的要求.表达式;否则行为未定义."

在C++ 0x中

一旦我自己理解了@litb提到的讨论细节,就会更新它.就目前而言,我只是把它搞砸了

但是,在C++ 0X中,据我所知,没有序列点的概念.此表达式很好,不会调用未定义的行为.这是因为++对'z'的影响在'z'上的赋值的副作用之前被排序.

$ 1.9/15-"除非另有说明,否则对单个运算符的操作数和单个表达式的子表达式的评估是不合理的.[注意:在程序执行期间不止一次评估的表达式中,对其进行的未经测序和不确定的顺序评估子表达式不需要在不同的评估中一致地执行.-end note]运算符的操作数的值计算在运算符的结果的值计算之前被排序.如果对标量对象的副作用相对于另一个没有排序对同一标量对象的副作用或使用相同标量对象的值进行值计算时,行为未定义.

$ 3.9/9 - "算术类型(3.9.1),枚举类型,指针类型,指向成员类型的指针(3.9.2),std :: nullptr_t和这些类型的cv限定版本(3.9.3)统称为标量类型."

请注意,在表达式'z = z ++;'中 其中z是标量变量,由于赋值运算符和后缀运算符++对'z'的副作用未被排序(它们都没有在另一个之前排序).

感谢@Prasoon提供了宝贵的意见,以便从原始版本中完善此帖子

  • @Prasoon Saurav:你在哪里? (2认同)
  • @Chubsdad:根据`x`和`y`的值,行为将是未定义的.但是我们有'x = 1`和'y = 1`所以对'++ z`的评估是有保证的,因此行为将是未定义的,因为`z`在两个序列点之间被多次修改[赋值和preincrement修改`z`两次,没有任何插入序列点].请注意,您的帖子包含来自C++ 0x草案的引用.在C++中,0x`i = ++ i`是一个定义良好的行为. (2认同)
  • 对不起因为我造成的所有困惑:) (2认同)

rus*_*lik -1

是的,它会编译。

但如果你问的是逻辑错误:

1)&&运算符引入了一个序列点,因为当它确定最终结果时,它可以终止表达式的求值(在这种情况下,一个0值可以终止求值),因此它甚至不会到达++zifxy部分零。

2)因为&&运算符是逻辑一,所以结果总是0或1,我怀疑这是否是你想要的。