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

jav*_*iry 3 c c# c++ unary-operator

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

我有这个代码片段:

int x = 2;
int y = x + 4 * ++x;
// what is y???
Run Code Online (Sandbox Code Playgroud)

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

// C/C++
y is 15
Run Code Online (Sandbox Code Playgroud)

但是通过c#我会得到的

// C#
y is 14
Run Code Online (Sandbox Code Playgroud)

为什么?


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
Run Code Online (Sandbox Code Playgroud)

Naw*_*waz 5

int y = x + 4 * ++x;
Run Code Online (Sandbox Code Playgroud)

在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;
Run Code Online (Sandbox Code Playgroud)

同样,如果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;
Run Code Online (Sandbox Code Playgroud)

在C#中,操作数需要从左到右进行计算,因此总是得到第一个给出14的结果.

  • 是不是未定义的行为,因为你在同一个表达式中读取和修改`x`,没有序列点将两者分开? (2认同)
  • @Javad C#遵循C#标准,C++遵循C++标准.两者是不同的.这只会给不懂两种语言的程序员带来问题,因此不应该用两种语言编程.无论如何,应该避免使用丑陋的代码. (2认同)