在L值中使用后缀增量

可能重复:
后增量算子的评估会以什么顺序发生?

请考虑以下代码段(在C中):

uint8_t index = 10; uint8_t arr[20]; arr[index++] = index; 

当我用gcc编译它时,它将arr [10]设置为10,这意味着直到整个赋值表达式之后才应用后缀增量。 我发现这有点令人惊讶,因为我期望增量返回原始值(10)然后增加到11,从而将arr [10]设置为11。

我在RValues中看过很多关于增量运算符的post,但在LValue表达式中没有。

谢谢。

一些标准语言:

6.5表达式

1表达式是一系列运算符和操作数,用于指定值的计算,或指定对象或函数,或生成副作用或执行其组合的操作和操作数。

2在前一个和下一个序列点之间,对象的存储值最多只能通过表达式的计算修改一次。 72)此外,先前的值应该是只读的,以确定要存储的值。 73)

3语法指示运算符和操作数的分组。 74)除了后面指定的(对于函数调用()&&||?:和逗号运算符),子表达式的评估顺序和副作用发生的顺序都是未指定的。

第2段明确地呈现formsa[i++] = i undefined的表达式; i的先前值不只是被读取以确定i++的结果。 因此,允许任何结果。

除此之外,您不能依赖于在评估表达式后立即应用++运算符的副作用。 对于像这样的表达式

 a[i++] = j++ * ++k 

唯一的保证是将表达式j++ * ++k结果赋给表达式a[i++] ; 然而,每个子表达式a[i++]j++++k可以按任何顺序进行评估 ,并且副作用(分配给a[i] ,更新i ,更新j和更新k )可以应用于任何订单。

这条线

 arr[index++] = index; 

导致未定义的行为。 阅读C标准了解更多详情。

您应该知道的本质是:您不应该在同一语句中读取和更改变量。

赋值操作从右到左工作,即首先计算表达式的右侧部分,然后将其分配给左侧部分。