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

时间:2010-10-03 14:00:36

标签: c++ c sequence-points

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

  z = x && y && ++z;//is this fine?
}

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

3 个答案:

答案 0 :(得分: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 ;
} 

注意:注意操作员和&&但那些在这个例子中并不相关。

精细!一般来说,可能是或可能不是。取决于x和y的值。在你的具体情况下,它并不好。此代码有可能包含undefined behavior

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

  

$ 5 / 4-“除非另有说明,否则订单   评估操作系统   个体经营者和   个人的子表达   表达式,以及其中的顺序   副作用发生,是   unspecified.53)之间的   下一个序列指向一个标量   对象应具有其存储值   最多修改一次   表达的评价。   此外,先前的值应为   只访问以确定值   存储。这个要求   应满足每一段   允许的订购   表达式的子表达式;   否则行为是不确定的。“

在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-qualified   这些类型的版本(3.9.3)是   统称为标量类型。“

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

感谢@Prasoon提供了有价值的输入,以便从原始版本中优化此帖子

答案 1 :(得分:2)

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

您的计划

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

  z = x && y && ++z;/*is this fine?*/

    return 0;
}

产生此警告:

x.c: In function 'main':
x.c:6:5: warning: operation on 'z' may be undefined

答案 2 :(得分:-2)

是的,它会编译。

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

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

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