简体   繁体   English

C 表达式的计算顺序是什么

[英]What is the order in which C expressions are evaluated

int main(){
 char a = 5;
 float b = 6.0;
 int c = a + b;
 return c;
}

Looking at the generate instructions with gcc, the above code is evaluated like this:用gcc查看生成指令,上面的代码是这样评估的:

  • Load 5 and convert it to float as a负载5,并将其转换为float作为a
  • Load 6 as b加载 6 作为b
  • Add a and b添加ab
  • Convert the result to an integer and return将结果转换为整数并返回

Does gcc not care about the return type while it's dealing with the expression? gcc 在处理表达式时不关心返回类型吗? It could have converted b to an int right off the bat as everything else is an integer type.它可以立即将b转换为int ,因为其他所有内容都是整数类型。

Is there a rule which explains how one side of an expression is evaluated first regardless of what the other side is?是否有规则可以解释如何首先评估表达式的一侧而不管另一侧是什么?

You ask "Is there a rule?"你问“有规定吗?” Of course there is a rule.当然是有规律的。 Any widely used programming language will have a huge set of rules.任何广泛使用的编程语言都会有一套庞大的规则。

You have an expression "a + b".你有一个表达式“a + b”。 a has type char, b has type float. a 有 char 类型,b 有 float 类型。 There's a rule in the C language that the compiler has to find a common type and convert both to the common type. C 语言中有一个规则,编译器必须找到一个公共类型并将两者都转换为公共类型。 Since one of the values is a floating-point type, the common type must be a floating-point type, which is float, double, or long double.由于其中一个值是浮点类型,因此公共类型必须是浮点类型,即 float、double 或 long double。 If you look closer at the rules, it turns out the common type must be float or double, and the compiler must document this.如果您仔细查看规则,就会发现公共类型必须是 float 或 double,并且编译器必须记录这一点。 It seems the compiler chose "float" as the common type.似乎编译器选择了“float”作为通用类型。

So a is converted from char to float, b is already float, both are added, the result has type float.所以a从char转换为float,b已经是float,两者相加,结果为float类型。 And then there's a rule that to assign float to int, a conversion takes place according to very specific rules.然后有一个规则,要将 float 分配给 int,根据非常具体的规则进行转换。

Any C compiler must follow these rules exactly.任何 C 编译器都必须严格遵守这些规则。 There is one exception: If the compiler can produce the results that it is supposed to produce then it doesn't matter how.有一个例外:如果编译器可以生成它应该生成的结果,那么如何生成都无关紧要。 As long as you can't distinguish it from the outside.只要你不能从外面区分它。 So the compiler can change the whole code to "return 11;".所以编译器可以把整个代码改成“return 11;”。

In the C language, partial expressions are evaluated without regard how they are used later.在 C 语言中,部分表达式的计算不考虑它们以后如何使用。 Whether a+b is assigned to an int, a char, a double, it is always evaluated in the same way.无论 a+b 是否分配给 int、char、double,它总是以相同的方式计算。 There are other languages with different rules, where the fact that a+b is assigned to an int could change how it is evaluated.还有其他具有不同规则的语言,其中将 a+b 分配给 int 的事实可能会改变它的评估方式。 C is not one of those languages. C 不是这些语言之一。

If you change it to:如果将其更改为:

int main(){
 char a = 5;
 float b = 6.6;
 int c = a + 2*b;
 return c;
}

then it becomes clear that you have to keep the float 18.2 until the end.那么很明显,您必须将浮动18.2保持到最后。

With no optimizations, gcc acts as if this could happen and does a lot of conversions.在没有优化的情况下,gcc 就好像这可能发生一样,并进行大量转换。

With just -O it already does the math itself and directly returns the final integer, even in above example.仅使用-O它已经自己进行数学运算并直接返回最终整数,即使在上面的示例中也是如此。

There is no in-between reasoning and short-cut here.这里没有中间推理和捷径。 Why simplify from 5+6.0 to 5+6 but not to 11 ?为什么从5+6.0简化为5+6而不是11 Either act stupid and do cvtsi2ss xmm1,eax (and back etc.), or then tell them directly 11 .要么装傻,做cvtsi2ss xmm1,eax (和 back 等),要么直接告诉他们11

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

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