4

在阅读The C Programming Language时,我注意到在评估顺序的优先级部分中指出“......函数调用、嵌套赋值语句以及递增和递减运算符会导致“副作用”......”。

我试图找到一些导致未定义行为的嵌套赋值语句的示例。在书中,它指出以下是可以

int nl, nw, nc;
nl = nw = nc = 0;

在那个nl, nw, 和nc将全部赋值0

然后,我遇到了这个状态:

x = y = y = z/3;    

不是“推荐”。所以我的问题是,这个陈述有什么问题?分配从右侧关联,因此该语句将等效于:

x = (y = (y = z/3));    

对我来说,似乎很清楚y = z/3and x = z/3。所以,如果是这种情况,那么任何人都可以给我一个嵌套赋值语句的例子,它可能导致未定义的行为,如果不是,你能解释为什么前面的语句是未定义的。

4

3 回答 3

4

赋值语句不限于单个变量。除其他外,您可以分配给数组的元素。

考虑这个嵌套赋值的例子:

int a[] = {100, 200};
a[a[1]] = a[1] = 0;

如果您评估分配的顺序,它应该如下工作:

a[1] = 0

完成此任务后,a如下所示:{100, 0}

a[a[1]] = 0

知道它a[1]为零,这与 相同a[0] = 0,因此数组应如下所示:{0, 0}

但是,问题是您现在指望 的副作用a[1] = 0在您进行下一个分配时已经完成:否则,您将零分配给a[100],这已经超出了数组的末尾。

由于在没有序列点的情况下未定义副作用的完成顺序,因此这是未定义的行为。

于 2013-11-11T02:15:40.377 回答
1

http://c-faq.com/expr/seqpoints.html有几点涉及您的问题。尤其是:

虽然y = y可能很好

x = y = y = z/3;

像这样的表达

y = y++

未定义,因为 的值y在序列点之前被修改了两次。

于 2013-11-11T02:16:50.603 回答
1

只有当某些表达式有副作用时,嵌套赋值才可能导致未定义的行为。在您发布的示例中,没有副作用,因此没有未定义的行为。但是,您链接到的页面也提供了一个未定义行为的示例:

x = y = y++;

他们并不是说所有嵌套的赋值都会导致未定义的行为,而只是说你应该避免它们,以避免可能使用那些做的事情。这更像是一种风格推荐。

于 2013-11-11T02:18:04.307 回答