为什么`x--> 0`不是未定义的行为,而`x = x - `是?

3 c operators decrement

众所周知,这通过零循环:

while (x-- > 0) { /* also known as x --> 0 */
  printf("x = %d\n", x);
}
Run Code Online (Sandbox Code Playgroud)

x = x--产生未定义的行为.


这两个例子都需要一些'返回'值x--,我猜不到.如何x-- > 0定义但x = x--不是?

Fre*_*son 19

因为x = x--你在x没有插入序列点的情况下修改了两次的值.因此,未定义操作顺序.在修改一次x-- > 0的值中x,并且明确定义评估结果x--将是x递减之前的值.

  • @Radek S:定义了`x = x - `中的任何内容.语言说`x = x - `是未定义的.这意味着整个事情是不确定的,而不仅仅是某些东西的"秩序". (2认同)
  • @hauntsaninja:对于未定义的行为,似乎正常工作是一个合理的结果.它也可以返回42并且符合要求.对于像这样的表达式,"正确"的结果没有合理的期望; 这取决于您对评估顺序的期望. (2认同)

AnT*_*AnT 7

我不知道你在哪里知道"需要一些'返回'的x值,这是不存在的".首先,你的意思并不清楚.其次,无论你的意思是什么,这似乎与未定义行为的来源没有任何关系x = x--.

x = x--产生未定义的行为,因为它试图修改x两次没有插入序列点.这里不涉及任何"返回值"的"需要".

潜在的问题x = x--是它有两个在未定义的时刻以未定义的顺序发生的副作用.赋值运算符引入了一个副作用.postfix --运算符引入了另一个副作用.两种副作用都试图修改相同的变量x并且通常相互矛盾.这就是为什么在这种情况下的行为在法律上被宣布为未定义的原因.

例如,如果原来的值x5,那么您的表达需要x成为两个4(递减的副作用)和5在相同的时间(分配的副作用).不用说,这是不可能的x,成为45在同一时间.

虽然UB不需要这种简单的矛盾(如4vs 5).每当你有两个副作用击中相同的变量而没有插入序列点时,行为是不确定的,即使这些副作用试图放入变量匹配的值.