void main(void)
{
int x,y,z;
x=y=z=1;
z = x && y && ++z;//is this fine?
}
我最近开始阅读关于序列点的东西,但我无法弄清楚上面的代码示例是否正常。我知道&&
运算符引入了一个序列点,所以我不太清楚表达式z = x&&的行为。 y&& ++ž。有人请告诉我正确的答案。
答案 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
值可以终止评估),因此如果++z
或x
为零,它甚至无法到达y
部分。
2)因为&&
运算符是逻辑运算符,结果将始终为0或1,我怀疑这是你想要的。