为什么x ++ – + – ++ x合法但x +++ – +++ x不合法?
我想知道为什么在C#中以下是好的:
int y = x++-+-++x;
但
int y = x+++-+++x;
是不是? 为什么对+有偏见?
另外两个答案是正确的; 我将补充一点,这说明了词法分析的一些基本原则:
- 词法分析器是近视的 – 它具有最小的“预见”
- 词法分析器是贪婪的 – 它试图制作它现在可以使用的最长的令牌。
- 当一个失败时,词法分析器不会回溯试图寻找替代解决方案。
这些原则意味着+++x
将被定义为++ + x
而不是+ ++ x
。
解析器然后将++ + x
解析为++(+x)
,而(+x)
不是变量 ,它是一个值 ,因此它不能递增。
另见: http : //blogs.msdn.com/b/ericlippert/archive/2010/10/11/10070831.aspx
我正在使用VS 2012.这很有趣。
第一个可以解析为:
int y = (x++) - (+(-(++x)));
而不改变最终结果。 所以你可以看出为什么它会有效。
然而,第二个问题与+++x
存在问题,因为(我猜)它看到了两个++,并尝试将该一元运算符应用于r值,这是另一个+(而不是有效的) r值)。 您可以通过各种方式对其进行分组以使其正常工作:
int y = (x++)+(-(+(++x)));
已validation。
我确定Jon Skeet或Eric Lippert或其他人会出现并指出C#规范的相关部分。 我甚至不确定从哪里开始。 但是,只需遵循一般的从左到右的令牌解析,您就可以看到它在第二个上会窒息。
编译器在int y = x+++-+++x
的第二个++
之后寻找变量或属性,并且如果没有空格或括号则无法确定。
你可以这样做:
int y = x+++-+(++x);
要么
int y = x++ + -+ ++x;
如果你想要的话。
你列出的第一个例子的原因是因为编译器可以从++x
确定+-
; 而在第二个例子中,它无法确定将+++
分开的位置,并且在读取第一个++
后自然会期望变量; 所以简而言之,编译器试图使用+x
作为变量,这是无效的。
两者都可能使用其他编译器有效。 这取决于语义。