将首先评估表达式的右侧

时间:2014-10-14 01:04:22

标签: c language-lawyer operator-precedence

右侧总是会在左侧前方进行评估吗?然后右侧的结果将传递到左侧。我不是在讨论诸如A[i]=i++

之类的例外

我说的是正常情况:

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

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

4 个答案:

答案 0 :(得分:5)

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

  

赋值运算符将值存储在由指定的对象中   左操作数。赋值表达式的值为left   赋值后的操作数,111)但不是左值。的类型   赋值表达式是左操作数之后的类型   左值转换。更新存储值的副作用   左操作数在左和右的值计算之后排序   正确的操作数。 对操作数的评估未经过排序

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

答案 1 :(得分:4)

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

由于您comment声明您对一般规则感兴趣:

  

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

draft C99 standard部分6.5 表达式3所涵盖的内容(强调我的前进):

  

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

这在draft C11 standard中基本相同,期望C11不列出异常,因此引用C99更方便。 C11中的第3段说:

  

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

专门针对赋值运算符 C99说:

  

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

和C11说:

  

[...]对操作数的评估没有考虑。

答案 2 :(得分:1)

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

int a[1], b=0;

a[b++] = b;

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

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

答案 3 :(得分:0)

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

可以找到完整列表here

相关问题