一元:为什么一元在c#中的行为因c / c ++而异

时间:2011-10-23 10:49:33

标签: c# c++ c unary-operator

  

可能重复:
  Undefined, unspecified and implementation-defined behavior
  Undefined Behavior and Sequence Points
  Pre & post increment operator behavior in 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

WHY吗


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

2 个答案:

答案 0 :(得分:5)

int y = x + 4 * ++x;

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

如果在x之前评估4*++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*++x之前评估x,那么

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的行为。

答案 1 :(得分:2)

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

C#作为一种安全的语言,不能允许这种情况,因此更严格地定义评估顺序。