在阅读 C编程语言时,我注意到在评估顺序部分的优先级中它指出“...函数调用,嵌套赋值语句和增量和递减运算符导致“副作用”......“。
我正在尝试查找导致未定义行为的嵌套赋值语句的一些示例。在本书中,它指出以下是 ok :
int nl, nw, nc;
nl = nw = nc = 0;
,nl
,nw
和nc
都将被分配0
。
然后,我遇到this声明:
x = y = y = z/3;
不“推荐”。所以我的问题是,这个陈述会出现什么问题?作业与右侧相关联,因此该陈述将等同于:
x = (y = (y = z/3));
对我来说,y = z/3
和x = z/3
似乎非常清楚。所以,如果是这种情况,那么任何人都可以给我一个嵌套赋值语句的例子,它可能导致未定义的行为,如果没有,你能解释为什么前面的语句是未定义的。
答案 0 :(得分: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
的副作用在您进入下一个作业时完成的事实:否则,您将{0}分配给a[100]
,这是超过数组末尾的方式。
由于在没有sequence points的情况下没有定义副作用的完成顺序,这是未定义的行为。
答案 1 :(得分:1)
http://c-faq.com/expr/seqpoints.html有几点涉及您的问题。特别是:
y = y
可能很好
x = y = y = z/3;
像
这样的表达式y = y++
未定义,因为y
的值在序列点之前被修改了两次。
答案 2 :(得分:1)
当某些表达式具有副作用时,嵌套赋值只会导致未定义的行为。在您发布的示例中,没有副作用,因此没有未定义的行为。但是,您链接到的页面也提供了未定义行为的示例:
x = y = y++;
他们并不是说所有嵌套的赋值都会导致未定义的行为,但只是你应该避免使用它们以避免使用那些行为。这更像是一种风格推荐。