一元:为什么 c# 中一元的行为随 c/c++ 的变化而变化

发布于 2024-12-11 05:08:06 字数 1103 浏览 0 评论 0原文

可能的重复:
未定义、未指定和实现定义的行为
未定义的行为和序列点
前置和后置C、C++、Java 和 & 中的后递增运算符行为C#

我有这个代码片段:

int x = 2;
int y = x + 4 * ++x;
// what is y???

当我在 c/c++ 中编译和测试它时,我会得到:

// C/C++
y is 15

但是通过 c#我会得到

// C#
y is 14

为什么?


IL的一部分是:

locals init ([0] int32 x,
[1] int32 y)
IL_0000: nop
IL_0001: ldc.i4.2
IL_0002: stloc.0
IL_0003: ldloc.0
IL_0004: ldc.i4.4
IL_0005: ldloc.0
IL_0006: ldc.i4.1
IL_0007: add
IL_0008: dup
IL_0009: stloc.0
IL_000a: mul
IL_000b: add
IL_000c: stloc.1
IL_000d: ldloca.s y

Possible Duplicate:
Undefined, unspecified and implementation-defined behavior
Undefined Behavior and Sequence Points
Pre & post increment operator behavior in C, C++, Java, & C#

I have this code-snippet:

int x = 2;
int y = x + 4 * ++x;
// what is y???

And when I compile and test it in c/c++ I'll get:

// C/C++
y is 15

But via c# I'll get

// C#
y is 14

WHY?


A part of IL is:

locals init ([0] int32 x,
[1] int32 y)
IL_0000: nop
IL_0001: ldc.i4.2
IL_0002: stloc.0
IL_0003: ldloc.0
IL_0004: ldc.i4.4
IL_0005: ldloc.0
IL_0006: ldc.i4.1
IL_0007: add
IL_0008: dup
IL_0009: stloc.0
IL_000a: mul
IL_000b: add
IL_000c: stloc.1
IL_000d: ldloca.s y

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

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

发布评论

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

评论(2

旧梦荧光笔 2024-12-18 05:08:07
int y = x + 4 * ++x;

在 C 和 C++ 中,每个操作数的求值顺序未指定,这意味着 x4*++x 可以在另一个之前求值。由于操作数的求值顺序未指定,因此整个表达式的结果也未指定。

如果 x4*++x 之前计算,则 y 将计算为:

int y = x + 4 * ++x; //original

int y = 2 + 4 * ++x  //evaluate x first
      = 2 + (4 * 3)  //evaluate 4 *++x then
      = 14;

类似地,如果 4*++xx 之前求值,然后

int y = x + 4 * ++x; //original

int y = x + (4*3)  //evaluate 4 * ++x first
      = 3 + 12   //evaluate x then  (x is incremented)
      = 15;

在 C# 中,操作数需要从左到右求值,因此您总是会得到第一个行为,结果为 14。

int y = x + 4 * ++x;

In C and C++, the order of evaluation of each operand is unspecified which means either x or 4*++x can be evaluated before the other. Since the order of evaluation of the operands is unspecified, the result of the entire expression is unspecified.

If x is evaluated before 4*++x, then y will be computed as:

int y = x + 4 * ++x; //original

int y = 2 + 4 * ++x  //evaluate x first
      = 2 + (4 * 3)  //evaluate 4 *++x then
      = 14;

Similarly, if 4*++x is evaluated before x, then

int y = x + 4 * ++x; //original

int y = x + (4*3)  //evaluate 4 * ++x first
      = 3 + 12   //evaluate x then  (x is incremented)
      = 15;

In C#, the operands are required to be evaluated left to right, so you always get the first behaviour giving 14 as a result.

深巷少女 2024-12-18 05:08:07

实际上,在 C++ 中,您只会得到未定义的行为,因为表达式的求值顺序并不总是指定的,因此不清楚第一次使用 x 是读取旧值还是新值。两者都是可能的,事实上任何事情都是可能的,因为标准明确指出发生的事情是不确定的。

C# 作为一种安全语言,不允许出现这种情况,因此更严格地定义了求值顺序。

Actually, in C++ you just get undefined behavior, since the evaluation order of expressions is not always specified, so it's unclear whether the first use of x reads the old or new value. Both are possible, and in fact anything at all is possible because the standard explicitly says that it is undefined what happens.

C#, as a safe language, cannot allow such a situation and thus more strictly defines order of evaluation.

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