【问题标题】:Why does this expression produce different results in C# and C++?为什么这个表达式在 C# 和 C++ 中会产生不同的结果?
【发布时间】:2011-05-16 12:48:04
【问题描述】:

我在 C# 和 C++ 中都尝试过以下代码:

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

我注意到b 的结果在 C# 和 C++ 中是不同的。在 C# 中,我得到了 23。在 C++ 中,我得到了 20。

为什么会这样?为什么相同的表达式会在 C# 和 C++ 中产生不同的结果?这是因为两种语言的运算符优先级规则不同吗?

【问题讨论】:

    标签: c# c++ operators expression operator-precedence


    【解决方案1】:

    C# 从左到右计算它。在 C++ 中,funny expressions(例如您的)调用 undefined behavior,因为您正在更改变量并再次读取它,而无需干预 sequence point

    这意味着允许不同的编译器(甚至是具有不同优化设置的相同编译器)(通常)为(a++)+(++a)+(a--)+(--a) 产生不同的结果。

    【讨论】:

      【解决方案2】:

      查看here 以获取 C++ 的完整列表。正如 FredOverflow 所说,C# 从左到右计算

      【讨论】:

        【解决方案3】:

        表达式在 C# 中具有明确定义的行为(从左到右求值)

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

        int b = (a++)+(++a)+(a--)+(--a);
        
              // 5   +   7 + 7   +   5 = 24
        

        在 C++ 中,表达式调用 Undefined Behaviour,因为 a 在两个 sequence points 之间被多次修改。

        【讨论】:

          【解决方案4】:

          无论如何都需要查一下,所以我想我也会在这里发布。

          来自 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 参数列表的运行时评估

          参数列表的表达式总是按照它们的写入顺序进行计算。因此,示例

          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++);
               }
          }
          

          产生输出

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

          【讨论】:

            猜你喜欢
            • 2016-11-13
            • 1970-01-01
            • 2016-11-04
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-10-07
            • 1970-01-01
            • 2021-11-06
            相关资源
            最近更新 更多