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

5
我已经在C#和C++中尝试了以下代码:
int a = 5;
int b = (a++)+(++a)+(a--)+(--a);

我注意到在C#和C++中,b的结果是不同的。在C#中,我得到了23,在C++中,我得到了20。
为什么会这样呢?为什么相同的表达式在C#和C++中会产生不同的结果?这是因为两种语言有不同的运算符优先级规则吗?
4个回答

6

C# 从左到右计算。在 C++ 中,像你这样的奇怪表达式会引起未定义行为,因为你在没有序列点的情况下更改了变量并再次读取它。

这意味着不同的编译器(甚至是相同编译器的不同优化设置)可以(并且通常)为(a++)+(++a)+(a--)+(--a)产生不同的结果。


4

在C#中,该表达式具有明确定义的行为(从左到右进行评估)

在C#中,输出将是24(而不是23)

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

      // 5   +   7 + 7   +   5 = 24

在C++中,该表达式会引发未定义行为,因为a在两个序列点之间被多次修改。


0

点击这里查看完整的C++列表。正如FredOverflow所说,C#从左到右进行评估。


0

我需要查找这个内容,所以想在这里发布一下。

来自C# 5.0规范

5.3.3.21 嵌套表达式的一般规则
以下规则适用于这些类型的表达式:带括号的表达式(§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)。
这些表达式中的每一个都有一个或多个子表达式,这些子表达式在固定顺序下无条件地进行评估(重点在此)。例如,二元 % 运算符首先计算运算符的左侧,然后计算右侧。索引操作计算索引表达式,然后按从左到右的顺序计算每个索引表达式。
每种表达式的详细规则在第7节中。我不会在这里列出所有规则,但是启发式规则是按照代码中编写的从左到右。例如。

7.5.1.2 Run-time evaluation of argument lists

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接