简体   繁体   English

将首先评估表达式的右侧

[英]will right hand side of an expression always evaluated first

Will right side always evaluated to ahead of left side? 右侧总是会在左侧前方进行评估吗? And then the result of right side will be passed on to left side. 然后右侧的结果将传递到左侧。 I am not talking about the exception such as A[i]=i++ 我不是在谈论A[i]=i++等异常

I am talking about the normal cases: 我说的是正常情况:

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

will the right part of all these expression evaluated first and then the result is compared to the left side? 将所有这些表达式的正确部分首先评估,然后将结果与左侧进行比较? (Always) (总是)

No, there is no such guarantee, N1570 §6.5.16/p3 (emphasis mine): 不,没有这样的保证,N1570§6.5.16/ p3(强调我的):

An assignment operator stores a value in the object designated by the left operand. 赋值运算符将值存储在左操作数指定的对象中。 An assignment expression has the value of the left operand after the assignment,111) but is not an lvalue. 赋值表达式在赋值后具有左操作数的值,111)但不是左值。 The type of an assignment expression is the type the left operand would have after lvalue conversion. 赋值表达式的类型是左值操作数在左值转换后将具有的类型。 The side effect of updating the stored value of the left operand is sequenced after the value computations of the left and right operands. 在左右操作数的值计算之后,对更新左操作数的存储值的副作用进行排序。 The evaluations of the operands are unsequenced . 对操作数的评估是不确定的

Note that assignment operator "consumes" two operands and has side-effect of modifying a lvalue. 请注意,赋值运算符“消耗”两个操作数,并且具有修改左值的副作用。

In general the order of evaluation of sub-expressions is unspecified, there are a few exceptions such as logical and , logical or , comma operator , etc... 一般来说,子表达式的评估顺序是未指定的,有一些例外,例如逻辑和 逻辑或 逗号运算符等......

Since you comment stated you are interested in the general rule: 由于您的评论声明您对一般规则感兴趣:

any operstor @YuHao if there is any general rule 任何操作员@YuHao,如果有任何一般规则

that would be covered by the draft C99 standard section 6.5 Expressions paragraph 3 which says ( emphasis mine going forward ): 这将被覆盖草案C99标准6.5 表达式3它说( 重点煤矿前进 ):

The grouping of operators and operands is indicated by the syntax.74) Except as specified later (for the function-call (), &&, ||, ?:, and comma operators), the order of evaluation of subexpressions and the order in which side effects take place are both unspecified . 运算符和操作数的分组由语法表示.74) 除了稍后指定的 (对于函数调用(),&&,||,?:和逗号运算符), 子表达式的评估顺序和顺序发生哪些副作用都是未指明的

this is basically the same in the draft C11 standard expect C11 does not list the exceptions so quoting C99 is more convenient. 这在C11标准草案中基本相同,期望C11没有列出异常,所以引用C99更方便。 Paragraph 3 in C11 says: C11第3段说:

The grouping of operators and operands is indicated by the syntax.85) Except as specified later, side effects and value computations of subexpressions are unsequenced .86) 运算符和操作数的分组由语法表示.85) 除了后面指出的,子表达式的副作用和值计算是未被排序的.86)

Specifically for assignment operators C99 says: 特别是对于赋值运算符 C99说:

The order of evaluation of the operands is unspecified [...] 操作数的评估顺序未指定[...]

and C11 says: 和C11说:

[...] The evaluations of the operands are unsequenced. [...]对操作数的评估没有统计。

I just encountered this today, and spent 1 hour debugging code like this: 我今天刚刚遇到这个,花了1个小时调试这样的代码:

int a[1], b=0;

a[b++] = b;

I expected a[0] to contain 0 after this, but the compiler actually decided to evaluate b++ first, then right side of assignment, and store result in a[0] (so b++ on the left side worked as it should). 我希望a [0]在此之后包含0,但是编译器实际上决定首先评估b ++,然后是赋值的右侧,并将结果存储在[0]中(因此左侧的b ++工作正常)。 So this effectively became: 所以这有效地成了:

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

This will depend on the precedence and associativity of the operators involved. 这取决于所涉及的运营商的优先级和相关性。

A full list can be found here 完整列表可以在这里找到

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM