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

void main(void) { int x,y,z; x=y=z=1; z = x && y && ++z;//is this fine? } 

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

在C ++ 03中。

 void main(void) { int x,y,z; x=y=z=1; // Seq1 at ; z = x && y && ++z;//is this fine? // Seq2 at ; } 

注意:请注意,运算符&&上有序列点,但这些在本例中不相关。

精细!。 通常,可能是或可能不是。 取决于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提供了宝贵的意见,以便从原始版本中完善此post

知道该行是否正常的简单方法是让编译器检查一下。 例如,gcc具有-Wsequence-point选项 (由-Wall启用),用于检查是否存在由于缺少序列点而导致的未定义行为。

你的计划

 int main(void) { int x,y,z; x=y=z=1; z = x && y && ++z;/*is this fine?*/ return 0; } 

产生这个警告:

 xc:在函数'main'中:
 xc:6:5:警告:'z'上的操作可能未定义

是的,它会编译。

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

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

2)因为&&运算符是逻辑运算符,结果将始终为0或1,我怀疑这是你想要的。