In all cases,the assignment is sequenced after the value computation
of the right and left operands,and before the value computation of
the assignment expression. With respect to an
indeterminately-sequenced function call,the operation of a compound
assignment is a single evaluation
根据我的理解,所有作为给定作业的一部分的表达式将在赋值本身之前进行评估.即使我在相同的作业中修改了相同的变量,这个规则也应该是正常的,我相当肯定,这是之前的未定义的行为.
会给定代码:
int a = 0; a = (a+=1) = 10; if ( a == 10 ) { printf("this is defined"); } else { printf("undefined"); }
总是评价为== 10?
解决方法
E1 = (E2 = E3)
其中E1是表达式a,E2是表达式a = 1,E3是表达式10.这里我们建议,赋值运算符从右到左(C11标准中的§5.17/ 1)组合.
§5.17/ 1另外说:
In all cases,the assignment is sequenced after the value computation of the right and left operands,and before the value computation of the assignment expression.
将其应用于我们的表达式意味着我们首先必须评估子表达式E1和E2 = E3.请注意,这两个评估之间没有“先后顺序”关系,但这不会导致任何问题.
id-expression E1的评估是微不足道的(结果是一个本身).赋值表达式E2 = E3的评估进行如下:
首先,两个子表达式都必须进行评估.对文字E3的评价再次微不足道(赋予价值10的价值).
(化合物)分配表达式E2的评估按以下步骤进行:
1)a = 1的行为相当于a = a 1但a只被评估一次(§5.17/ 7).在对子表达式a和1(按任意顺序)进行评估之后,对值进行左值转换,以读取存储在a中的值.
2)a(其为0)和1的值被添加(a 1),并且该添加的结果是值1的pr值.
3)在我们可以计算分配结果a = a 1之前,左操作数引用的对象的值被右操作数的值替换(§5.17/ 2).因此,E2的结果是对新值1的左值.注意,在赋值表达式的值计算之前,排除副作用(更新左操作数的值).这是上面引用的§5.17/ 1.
现在我们已经对子表达式E2和E3进行了评估,E2ref表达式的值被E3替换为10,因此E2 = E3的结果是值为10的值.
最后,值表达式E1指代被表达式E2 = E3的值所替代,我们计算为10.因此,变量赋值为包含值10.
由于所有这些步骤都有明确的定义,因此整个表达式产生了明确的值.