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

发布于 2024-10-04 15:49:04 字数 245 浏览 1 评论 0原文

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

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

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

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

I have tried the following code in both C# and C++:

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

I noticed that the result of b is different in C# and C++. In C#, I got 23. In C++, I got 20.

Why is this so? Why would an identical expression produce different results in C# and C++? Is this because the two languages have different operator precedence rules?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

热鲨 2024-10-11 15:49:04

C# 从左到右计算它。在 C++ 中,有趣的表达式(例如您的表达式)会调用 未定义的行为,因为您正在更改变量并再次读取它,而没有插入序列点

这意味着不同的编译器(甚至是具有不同优化设置的同一编译器)可以(并且通常将会)为 (a++)+(++a)+(a --)+(--a)

C# evaluates this from left to right. 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.

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).

软糖 2024-10-11 15:49:04

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

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

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

      // 5   +   7 + 7   +   5 = 24

在 C++ 中,表达式调用 未定义行为,因为 a< /code> 在两个序列点之间修改多次。

The expression has well-defined behavior in C# (evaluation from left to right)

In C#, the output would be 24 (not 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.

心凉怎暖 2024-10-11 15:49:04

请在此处查看 C++ 的完整列表。正如 FredOverflow 所说,C# 从左到右计算

Take a look here for the complete list for C++. As FredOverflow says, C# evaluates from left to right

少钕鈤記 2024-10-11 15:49:04

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

来自 C# 5.0 规范

5.3.3.21 具有嵌入表达式的表达式的一般规则

以下规则适用于这些类型的表达式:括号表达式(第 7.6.3 节)、元素访问表达式(第 7.6.6 节)、带索引的基本访问表达式(第 7.6.8 节)、递增和递减表达式(第 7.6.6 节) 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 参数列表的运行时评估

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

类测试
{
     静态无效 F(int x, int y = -1, int z = -2) {
          System.Console.WriteLine("x = {0}, y = {1}, z = {2}", x, y, z);
     }
     静态无效主(){
          整数 i = 0;
          F(i++, i++, i++);
          F(z: i++, x: i++);
     }
}

产生输出

<前><代码>x = 0,y = 1,z = 2
x = 4,y = -1,z = 3

Needed to look this up anyway so figured I would post it here too.

From The C# 5.0 Spec

5.3.3.21 General rules for expressions with embedded expressions

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).

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. E.g.

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文