将首先评估表达式的右侧

右侧是否会一直评估在左侧之前? 然后右侧的结果将传递到左侧。 我不是在谈论A[i]=i++等exception

我说的是正常情况:

 A[i] = (j+32+43 & K); A[j] != (A[j] + A[k]); 

首先评估所有这些表达式的正确部分,然后将结果与左侧进行比较? (总是)

一般来说,子表达式的评估顺序是未指定的,有一些例外,例如逻辑和 逻辑或 逗号运算符等……

由于您的评论声明您对一般规则感兴趣:

任何操作员@YuHao,如果有任何一般规则

C99标准第6.5节草案所涵盖的内容将表示( 强调我的未来 ):

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

这在C11标准草案中基本相同,期望C11没有列出exception,所以引用C99更方便。 C11第3段说:

运算符和操作数的分组由语法表示.85) 除了后面指出的,子表达式的副作用和值计算是未被排序的.86)

特别是对于赋值运算符 C99说:

操作数的评估顺序未指定[…]

和C11说:

[…]对操作数的评估没有统计。

不,没有这样的保证,N1570§6.5.16/ p3(强调我的):

赋值运算符将值存储在左操作数指定的对象中。 赋值表达式具有赋值后的左操作数的值,111)但不是左值。 赋值表达式的类型是左值操作数在左值转换后将具有的类型。 在左右操作数的值计算之后,对更新左操作数的存储值的副作用进行排序。 对操作数的评估是不确定的

请注意,赋值运算符“消耗”两个操作数,并且具有修改左值的副作用。

我今天刚遇到这个,花了1个小时调试这样的代码:

 int a[1], b=0; a[b++] = b; 

我希望a [0]在此之后包含0,但编译器实际上决定首先评估b ++,然后是赋值的右侧,并将结果存储在[0]中(因此左侧的b ++工作正常)。 所以这有效地成了:

 b++; a[0] = b; // 1 

这取决于所涉及的运营商的优先级和相关性。

完整列表可以在这里找到