一元:为什么 c# 中一元的行为随 c/c++ 的变化而变化
可能的重复:
未定义、未指定和实现定义的行为
未定义的行为和序列点
前置和后置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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
在 C 和 C++ 中,每个操作数的求值顺序未指定,这意味着
x
或4*++x
可以在另一个之前求值。由于操作数的求值顺序未指定,因此整个表达式的结果也未指定。如果
x
在4*++x
之前计算,则y
将计算为:类似地,如果
4*++x
在x
之前求值,然后在 C# 中,操作数需要从左到右求值,因此您总是会得到第一个行为,结果为 14。
In C and C++, the order of evaluation of each operand is unspecified which means either
x
or4*++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 before4*++x
, theny
will be computed as:Similarly, if
4*++x
is evaluated beforex
, thenIn C#, the operands are required to be evaluated left to right, so you always get the first behaviour giving 14 as a result.
实际上,在 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.