简体   繁体   English

为什么这个表达式在 C# 和 C++ 中产生不同的结果?

[英]Why does this expression produce different results in C# and C++?

I have tried the following code in both C# and C++:我在 C# 和 C++ 中都尝试过以下代码:

int a = 5;
int b = (a++)+(++a)+(a--)+(--a);

I noticed that the result of b is different in C# and C++.我注意到b的结果在 C# 和 C++ 中是不同的。 In C#, I got 23. In C++, I got 20.在 C# 中,我得到了 23。在 C++ 中,我得到了 20。

Why is this so?为什么会这样? Why would an identical expression produce different results in C# and C++?为什么相同的表达式在 C# 和 C++ 中会产生不同的结果? Is this because the two languages have different operator precedence rules?这是因为两种语言的运算符优先级规则不同吗?

C# evaluates this from left to right. C# 从左到右评估它。 In C++, funny expressions such as yours invoke undefined behavior , because you are changing a variable and reading it again without an intervening sequence point .在 C++ 中,像您这样有趣的表达式会调用未定义的行为,因为您正在更改变量并再次读取它而没有中间序列点

This means that different compilers (or even the same compiler with different optimization settings) are allowed to (and typically will ) produce different results for (a++)+(++a)+(a--)+(--a) .这意味着允许不同的编译器(甚至是具有不同优化设置的相同编译器)(并且通常)为(a++)+(++a)+(a--)+(--a)产生不同的结果。

The expression has well-defined behavior in C# (evaluation from left to right)表达式在 C# 中有明确定义的行为(从左到右求值)

In C#, the output would be 24 (not 23)在 C# 中,输出将是24 (不是 23)

int b = (a++)+(++a)+(a--)+(--a);

      // 5   +   7 + 7   +   5 = 24

In C++, the expression invokes Undefined Behaviour because a is modified more than once between two sequence points .在 C++ 中,表达式调用未定义行为,因为a在两个序列点之间被修改了多次。

Take a look here for the complete list for C++.在此处查看 C++ 的完整列表。 As FredOverflow says, C# evaluates from left to right正如 FredOverflow 所说,C# 从左到右求值

Needed to look this up anyway so figured I would post it here too.无论如何都需要查一下这个,所以我想我也会把它贴在这里。

From The C# 5.0 Spec来自 C# 5.0 规范

5.3.3.21 General rules for expressions with embedded expressions 5.3.3.21 带有嵌入表达式的表达式的一般规则

The following rules apply to these kinds of expressions: parenthesized expressions (§7.6.3), element access expressions (§7.6.6), base access expressions with indexing (§7.6.8), increment and decrement expressions (§7.6.9, §7.7.5), cast expressions (§7.7.6), unary +, -, ~, * expressions, binary +, -, *, /, %, <<, >>, <, <=, >, >=, ==, !=, is, as, &, |, ^ expressions (§7.8, §7.9, §7.10, §7.11), compound assignment expressions (§7.17.2), checked and unchecked expressions (§7.6.12), plus array and delegate creation expressions (§7.6.10).以下规则适用于这些类型的表达式:括号表达式(第 7.6.3 节)、元素访问表达式(第 7.6.6 节)、带索引的基访问表达式(第 7.6.8 节)、递增和递减表达式(第 7.6.9 节) , §7.7.5), 转换表达式 (§7.7.6), 一元 +, -, ~, * 表达式, 二进制 +, -, *, /, %, <<, >>, <, <=, >, >=、==、!=、is、as、&、|、^ 表达式(第 7.8 节、第 7.9 节、第 7.10 节、第 7.11 节)、复合赋值表达式(第 7.17.2 节)、检查和未检查表达式(第 7.6 节) .12),加上数组和委托创建表达式(第 7.6.10 节)。

Each of these expressions has one or more sub-expressions that are unconditionally evaluated in a fixed order (emphasis mine) .这些表达式中的每一个都有一个或多个子表达式,它们以固定顺序无条件地求值(强调我的) For example, the binary % operator evaluates the left hand side of the operator, then the right hand side.例如,二元 % 运算符先计算运算符的左侧,然后再计算右侧。 An indexing operation evaluates the indexed expression, and then evaluates each of the index expressions, in order from left to right.索引操作计算索引表达式,然后按从左到右的顺序计算每个索引表达式。

The detailed rules for each kind of expression are in section 7. I won't list them all here, but the heuristic is left to right as written in code.每种表达式的详细规则在第 7 节中。我不会在这里列出它们,但启发式是从左到右写在代码中的。 Eg例如

7.5.1.2 Run-time evaluation of argument lists 7.5.1.2 参数列表的运行时评估

The expressions of an argument list are always evaluated in the order they are written.参数列表的表达式总是按照它们的编写顺序进行计算。 Thus, the example因此,例子

class Test { static void F(int x, int y = -1, int z = -2) { System.Console.WriteLine("x = {0}, y = {1}, z = {2}", x, y, z); } static void Main() { int i = 0; F(i++, i++, i++); F(z: i++, x: i++); } }

produces the output产生输出

x = 0, y = 1, z = 2 x = 4, y = -1, z = 3

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

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