几天前,这里讨论了表达式i = ++i + 1是否会引发未定义行为(Undefined Behavior)。
最终得出结论:由于'i'的值在两个序列点之间变化了多次,因此它会引发未定义行为。
我曾在同一帖子中与Johannes Schaub进行过讨论。他认为: i=(i,i++,i)+1 ------ (1) /* 也会引发未定义行为 */ 我则认为(1)不会引发未定义行为,因为逗号操作符','在i和i++之间以及i++和i之间清除了前面子表达式的副作用。
然后他给出了以下解释:
“是的,i++后的序列点会在它之前完成所有副作用,但没有什么能阻止赋值的副作用与i++的副作用重叠。根本问题在于赋值的副作用未指定发生在赋值操作数的评估之前还是之后,因此序列点无法保护这一点:序列点引入了一个部分顺序:仅仅因为i++之前和之后有一个序列点并不意味着所有副作用都按照i排序。
此外,请注意,仅仅一个序列点并不代表什么:代码的形式并不能决定评估的顺序。它由语义规则来决定。在这种情况下,没有语义规则说明赋值的副作用何时发生与其操作数或这些操作数的子表达式的评估相关。”
粗体字部分的陈述让我困惑了。据我所知:
“在执行序列中的某些指定点(称为序列点),先前评估的所有副作用都应该完成,并且随后的评估不应该产生任何副作用。”
既然逗号运算符也指定了执行顺序,当我们到达最后一个i时,i++的副作用已经被取消了。如果评估顺序未指定,则Johannes可能是正确的(但在逗号运算符的情况下,它已经很好地指定了)。
因此,我只想知道(1)是否会引起UB。有人能给出另一个有效的解释吗?
谢谢!
最终得出结论:由于'i'的值在两个序列点之间变化了多次,因此它会引发未定义行为。
我曾在同一帖子中与Johannes Schaub进行过讨论。他认为: i=(i,i++,i)+1 ------ (1) /* 也会引发未定义行为 */ 我则认为(1)不会引发未定义行为,因为逗号操作符','在i和i++之间以及i++和i之间清除了前面子表达式的副作用。
然后他给出了以下解释:
“是的,i++后的序列点会在它之前完成所有副作用,但没有什么能阻止赋值的副作用与i++的副作用重叠。根本问题在于赋值的副作用未指定发生在赋值操作数的评估之前还是之后,因此序列点无法保护这一点:序列点引入了一个部分顺序:仅仅因为i++之前和之后有一个序列点并不意味着所有副作用都按照i排序。
此外,请注意,仅仅一个序列点并不代表什么:代码的形式并不能决定评估的顺序。它由语义规则来决定。在这种情况下,没有语义规则说明赋值的副作用何时发生与其操作数或这些操作数的子表达式的评估相关。”
粗体字部分的陈述让我困惑了。据我所知:
“在执行序列中的某些指定点(称为序列点),先前评估的所有副作用都应该完成,并且随后的评估不应该产生任何副作用。”
既然逗号运算符也指定了执行顺序,当我们到达最后一个i时,i++的副作用已经被取消了。如果评估顺序未指定,则Johannes可能是正确的(但在逗号运算符的情况下,它已经很好地指定了)。
因此,我只想知道(1)是否会引起UB。有人能给出另一个有效的解释吗?
谢谢!