标准C中表达式i=(i=1)+1的定义性及与i=++i+1的序列点差异问询
C语言赋值表达式相关问题解答
问题1:在标准C中,表达式i = (i = 1) + 1;是否定义良好?
是,该表达式行为完全确定。按照C标准的求值规则,子表达式(i = 1)会先完成求值(包括将1赋值给i的副作用),之后才会执行加法运算+1,最后将加法结果(2)赋值给i。整个过程中所有操作的顺序明确,无未定义行为,最终i的值为2。
问题2:从序列点(或C11及以后的“副作用排序”)角度,该表达式与i = ++i + 1;有哪些差异?
i = (i = 1) + 1;:内部赋值i=1的副作用(修改i)会在加法运算和外部赋值之前彻底完成。两次修改i的操作有明确先后顺序,无冲突。i = ++i + 1;:++i的自增副作用与外部赋值的修改副作用之间没有明确顺序约束,也无序列点隔开这两次操作。根据C标准,同一对象在无序列点的情况下被多次修改属于未定义行为——编译器可任意排序操作,甚至产生不可预料的结果。
问题3:有人称i = (i = 1) + 1;中(i=1)之后存在序列点,因此表达式定义良好,这种说法是否正确?
不正确。括号本身不会引入序列点,C标准中的序列点仅来自特定运算符(如&&、||、?:)、完整表达式结束、函数调用等场景,括号仅改变运算优先级,不产生序列点。
该表达式之所以定义良好,是因为内部赋值表达式的求值(含副作用)必须在加法运算执行前完成,加法结果又必须在外部赋值执行前完成——这由运算符的求值规则决定,与序列点无关。
内容的提问来源于stack exchange,提问作者Jollioke Muzaom D
相关产品推荐
相关产品推荐

