11

我想知道为什么在 C# 中以下是好的:

int y = x++-+-++x;

int y = x+++-+++x;

不是吗?为什么对+有偏见?

4

3 回答 3

16

其他两个答案是正确的;我要补充一点,这说明了词法分析的一些基本原则:

  • 词法分析器是短视的——它有最小的“前瞻”
  • 词法分析器是贪婪的——它试图制作它现在能做的最长的标记。
  • 当一个失败时,词法分析器不会回溯尝试寻找替代解决方案。

这些原则意味着+++x将使用 as++ + x和 not + ++ x

然后解析器将解析++ + x++(+x),并且(+x)不是变量,而是,因此不能递增。

另见:http: //blogs.msdn.com/b/ericlippert/archive/2010/10/11/10070831.aspx

于 2013-07-11T18:02:07.103 回答
5

我正在使用 VS 2012。这很有趣。

第一个可以解析为:

int y = (x++) - (+(-(++x)));

在不改变最终结果的情况下。所以你可以看到为什么它是有效的。

然而,第二个有问题,+++x因为(我猜)它看到两个 ++ 并尝试将该一元运算符应用于 r 值,这是另一个 + (而不是有效的 r 值) . 但是,您可以通过各种方式对其进行分组以使其工作:

int y = (x++)+(-(+(++x)));

已验证。

我确信 Jon Skeet 或 Eric Lippert 或有人会出现并指出 C# 规范的相关部分。我什至不知道从哪里开始。但是只要按照一般的从左到右的令牌解析,您就可以看到它会在第二个令牌上阻塞。

于 2013-07-11T17:44:09.183 回答
2

++编译器在第二个输入之后寻找变量或属性int y = x+++-+++x,如果没有空格或括号则无法确定。

您可以执行以下操作:

int y = x+++-+(++x); 

或者

int y = x++ + -+ ++x;

如果你愿意。

您列出的第一个示例有效的原因是编译器可以+-++x; 而在第二个示例中,它无法确定在哪里分隔+++并且在读取第一个之后自然会期待一个变量++;所以简而言之,编译器试图+x用作变量,这是无效的。

两者都可能使用其他编译器有效。这取决于语义。

于 2013-07-11T17:44:52.763 回答